+1 (315) 557-6473 

Create A Game Of Hangman In ARM Assembly Language ARM Assembly Language Assignment Solution.


Instructions

Objective
Write an ARM assignment program to create a game of Hangman in assembly language.

Requirements and Specifications

You are going to write an ARM assembly program that allows a human to play of game of Hangman.
In this game, the player is attempting to guess a hidden word, one letter at a time.
You are given a text file with 10 words for the game:
  • TESTS
  • CHALLENGE
  • UNIVERSITY
  • STUDENTS
  • BALANCE
  • FEEDBACK
  • BINARY
  • INTELLIGENCE
  • CARTOGRAPHERS
  • CHARACTERISTICALLY
  1. A random secret word is read from the text file. Alternatively, you can list the 10 words in an array in the program (slightly less marks are given for this option) and choose a random word from the array.
  2. The player has six chances to guess the letters for each game.
  3. Valid inputs of the game are from A-Z or a-z (convert the letter into a capital if a small letter is input).
  4.  For each correct letter guessed, the letter is revealed at its correct location or locations in the word.
  5. For each incorrect letter guessed, an additional segment of the stick figure "hangman" is displayed.
  6. The stick figure has 6 segments in total: head, body, left and right arms, and left and right legs.
  7. The game is won when the entire word is guessed.
  8. The game is lost when the entire hangman is displayed.
  9. The game is exited upon winning, losing, or the player entering the 0 (zero) character.
  10. When the game is finished, the player can choose to have another round.
  11. You should not allow the player to make an illegal move, or to enter invalid characters. For example, a player can't guess the same letter twice, or enter a number (except 0 for exiting the game), or enter a non-printable character.

    Screenshots of output

    Create a game of Hangman in ARM assembly languageCreate a game of Hangman in ARM assembly language 1Create a game of Hangman in ARM assembly language 2Create a game of Hangman in ARM assembly language 3 Create a game of Hangman in ARM assembly language 4Create a game of Hangman in ARM assembly language 5

    Source Code

    .data

    author: .asciz "????"

    welcomeMsg: .ascii "/---------------------------------------------/\n"

                .ascii "/ Welcome to Hangman! /\n"

                .ascii "/ /\n"

                .ascii "/ Author: %-36s/\n"

                .ascii "/ Instructions: /\n"

                .ascii "/ Guess the hidden word one letter at a time/\n"

                .ascii "/ enter 0 to exit the game. /\n"

                .asciz "/---------------------------------------------/\n"

    hangman01: .ascii "\n"

                .ascii " |-----| Word: %s\n"

                .ascii " | |\n"

                .asciz " "

    hangman02: .asciz "O"

    hangman03: .ascii " | Misses: %s\n"

                .asciz " "

    hangman04: .asciz "\\"

    hangman05: .asciz "|"

    hangman06: .asciz "/"

    hangman07: .ascii " |\n"

                .asciz " "

    hangman08: .asciz "|"

    hangman09: .ascii " |\n"

                .asciz " "

    hangman10: .asciz "/"

    hangman11: .asciz " "

    hangman12: .asciz "\\"

    hangman13: .ascii " |\n"

                .ascii " |\n"

                .asciz " ---------\n"

    space: .asciz " "

    prompt: .asciz "Enter next character (A-Z), or 0 (zero) to exit: "

    tryAgain: .asciz "Invalid or repeated letter. Please try again.\n\n"

    intfmt: .asciz "%d"

    youLose: .asciz "You lose - out of moves\n\n"

    youWin: .asciz "Congratulation - you win!\n\n"

    showSecret: .asciz "Secret word: %s\n\n"

    playAgain: .asciz "Play again (y/n)?: "

    filename: .asciz "words.txt"

    openfmt: .asciz "rt"

    openError: .asciz "Unable to open word file: \"words.txt\"\n"

    memError: .asciz "Out of memory!\n"

    words: .space 200 @ space for 50 words

    curword: .space 40

    misses: .space 40

    .text

    .align 2

    .global main

    .type main, %function

    main:

        push {fp, lr} @ save fp and lr on stack

        mov r0, #0 @ call time(0)

        bl time

        bl srand @ call srand (time(0)) to set seed for random generator

        @ open word file

        ldr r0, =filename @ give filename

        ldr r1, =openfmt @ format to open for read only

        bl fopen @ open the file

        cmp r0, #0 @ if not valid file

        beq invalidFile @ terminate with error

        mov r4, r0 @ save file descriptor in r4

        @ count chars in file

        mov r5, #0 @ chars = 0

    fcLoop:

        mov r0, r4 @ use file descriptor

        bl fgetc @ read char from file

        cmp r0, #0 @ if end of file

        ble endfc @ end count

        add r5, r5, #1 @ increment char count

        b fcLoop @ repeat until eof

    endfc:

        mov r0, r5 @ allocate space for file

        bl malloc

        cmp r0, #0 @ if out of memory

        beq noMem @ print error and exit

        mov r5, r0 @ save allocated pointer in r5

        mov r0, r4 @ use file descriptor

        mov r1, #0 @ move to offset 0

        mov r2, #0 @ from start of file

        bl fseek @ rewind file

        @ load lines

        ldr r6, =words @ point to word table

        mov r7, #0 @ set number of words to zero

        mov r8, #0 @ index

        mov r9, #0 @ chars in line

    loadLoop:

        add r0, r5, r8 @ get current position in buffer

        str r0, [r6, r7, lsl #2] @ save pointer in table

        mov r9, #0 @ number of characters in line

    lineLoop:

        mov r0, r4 @ use file descriptor

        bl fgetc @ read char from file

        cmp r0, #0 @ if end of file

        ble endLoad @ end count

        cmp r0, #10 @ if newline

        beq endLine @ end line loop

        strb r0, [r5, r8] @ save char in buffer

        add r8, r8, #1 @ increment position in buffer

        add r9, r9, #1 @ increment characters in line

        b lineLoop @ repeat

    endLine:

        mov r0, #0 @ save end of string

        strb r0, [r5, r8] @ save eos in buffer

        add r8, r8, #1 @ increment position in buffer

        cmp r9, #0 @ if empty line

        beq loadLoop @ don't save in table

        add r7, r7, #1 @ increment number of words

        b loadLoop @ repeat

    endLoad:

        mov r0, #0 @ save end of string

        strb r0, [r5, r8] @ save eos in buffer

        cmp r9, #0 @ if empty line

        beq skip @ don't save in table

        add r7, r7, #1 @ else, increment number of words

    skip:

        mov r0, r4 @ load file descriptor

        bl fclose @ close file

        ldr r0, =welcomeMsg @ print welcome message

        ldr r1, =author

        bl printf

        mov r4, r5 @ put allocated buffer pointer in r4

        mov r5, r7 @ put number of words in r5

    startGame:

        @select word at random

        bl rand

        mov r1, r5 @ divide random number by number of words

        bl div

        @ load random word

        ldr r0, =words @ load word table address

        ldr r6, [r0, r1, lsl #2] @ load word pointer from table

        mov r0, r6

        ldr r1, =curword

        bl initCurWord @ fill current word

        ldr r0, =misses

        mov r1, #0

        strb r1, [r0] @ set empty string in misses

        mov r7, #0 @ set zero incorrect letters

    gameLoop:

        ldr r0, =curword @ load current word

        mov r1, r7 @ load number of incorrect letters

        ldr r2, =misses @ load current misses

        bl printHangman @ print current hangman

    try:

        ldr r0, =prompt @ prompt for input

        bl printf

        bl readChar @ read letter

        mov r8, r0 @ save read char

        cmp r8, #'0' @ if 0, exit

        beq gameEnd

        cmp r8, #'A' @ if < 'A'

        blt invalid @ print invalid

        cmp r8, #'Z' @ if >='A' && <='Z'

        ble checkGuess @ check guess

        cmp r8, #'a' @ if < 'a'

        blt invalid @ print invalid

        cmp r8, #'z' @ if >'z'

        bgt invalid @ print invalid

    toUpper:

        sub r8, r8, #32 @ convert to uppercase

    checkGuess:

        mov r0, r8 @ load letter in r0

        ldr r1, =misses

        bl searchLetter @ search letter in missed letters

        cmp r0, #0 @ see if it was found

        bne invalid @ if so, try again

        mov r0, r8

        ldr r1, =curword

        bl searchLetter @ search letter in guessed letters

        cmp r0, #0 @ see if it was found

        bne invalid @ if so, try again

        mov r0, r8

        mov r1, r6

        bl searchLetter @ search letter in word

        cmp r0, #0 @ see if it was found

        bne goodGuess @ if in word, it was a good guess

        ldr r0, =misses @ save character in misses

        strb r8, [r0, r7]

        add r7, r7, #1 @ increment incorrects

        mov r1, #0

        strb r1, [r0, r7] @ save end of string in misses

        cmp r7, #6 @ see if there were 6 misses

        beq gameLost @ if so, the game ended

        b gameLoop @ else, continue game

    goodGuess:

        mov r0, r8 @ load letter

        ldr r1, =curword @ load current

        mov r2, r6 @ load word

        bl uncoverLetters @ uncover all selected letters in word

        ldr r0, =curword @ load current

        mov r1, r6 @ load word

        bl strEqual @ see if all letters were uncovered

        cmp r0, #0 @ if not equal

        bne gameLoop @ repeat loop

    gameWin:

        ldr r0, =curword @ load current word

        mov r1, r7 @ load number of incorrect letters

        ldr r2, =misses @ load current misses

        bl printHangman @ print current hangman

        ldr r0, =youWin @ print win message

        bl printf

        b askRepeat @ ask if we must continue game

    gameLost:

        ldr r0, =curword @ load current word

        mov r1, r7 @ load number of incorrect letters

        ldr r2, =misses @ load current misses

        bl printHangman @ print current hangman

        ldr r0, =youLose @ print lose message

        bl printf

        ldr r0, =showSecret @ print secret message

        mov r1, r6

        bl printf

    askRepeat:

        ldr r0, =playAgain @ prompt to play again

        bl printf

        bl readChar @ read character

        cmp r0, #'y' @ if continue y

        beq startGame @ start over

        cmp r0, #'Y' @ if continue Y

        beq startGame @ start over

        b gameEnd @ else, terminate game

    invalid:

        ldr r0, =tryAgain @ ask to try again

        bl printf

        b try @ repeat

    invalidFile:

        ldr r0, =openError @ print error message

        bl printf

        b terminate

    noMem:

        ldr r0, =memError @ print error message

        bl printf

    gameEnd:

        mov r0, r4 @ load allocated buffer pointer

        bl free @ free memory

    terminate:

        pop {fp, lr} @ restore fp and lr from stack

        bx lr @ return

    @ Print the hangman using r0 = current word, r1 = current incorrect guesses,

    @ r2 = misses

    .global printHangman

    .type printHangman, %function

    printHangman:

        push {r4, r5, fp, lr}

        mov r4, r1 @ load incoreect guesses in r4

        mov r5, r2 @ load current misses in r5

        mov r1, r0 @ load current uncovered word

        ldr r0, =hangman01 @ load hangman string

        bl printf @ print it

        cmp r4, #0

        beq skip1

        ldr r0, =hangman02 @ load hangman string

        b print1

    skip1:

        ldr r0, =space @ load hangman string

    print1:

        bl printf @ print it

        ldr r0, =hangman03 @ load hangman string

        mov r1, r5 @ load current misses

        bl printf @ print it

        cmp r4, #3

        blt skip2

        ldr r0, =hangman04 @ load hangman string

        b print2

    skip2:

        ldr r0, =space @ load hangman string

    print2:

        bl printf @ print it

        cmp r4, #2

        blt skip3

        ldr r0, =hangman05 @ load hangman string

        b print3

    skip3:

        ldr r0, =space @ load hangman string

    print3:

        bl printf @ print it

        cmp r4, #4

        blt skip4

        ldr r0, =hangman06 @ load hangman string

        b print4

    skip4:

        ldr r0, =space @ load hangman string

    print4:

        bl printf @ print it

        ldr r0, =hangman07 @ load hangman string

        bl printf @ print it

        cmp r4, #2

        blt skip5

        ldr r0, =hangman08 @ load hangman string

        b print5

    skip5:

        ldr r0, =space @ load hangman string

    print5:

        bl printf @ print it

        ldr r0, =hangman09 @ load hangman string

        bl printf @ print it

        cmp r4, #5

        blt skip6

        ldr r0, =hangman10 @ load hangman string

        b print6

    skip6:

        ldr r0, =space @ load hangman string

    print6:

        bl printf @ print it

        ldr r0, =hangman11 @ load hangman string

        bl printf @ print it

        cmp r4, #6

        blt skip7

        ldr r0, =hangman12 @ load hangman string

        b print7

    skip7:

        ldr r0, =space @ load hangman string

    print7:

        bl printf @ print it

        ldr r0, =hangman13 @ load hangman string

        bl printf @ print it

        pop {r4, r5, fp, lr}

        bx lr

    @ Fills underscores as current guessed word, r0 = word, r1 = current word

    .global initCurWord

    .type initCurWord, %function

    initCurWord:

        mov r2, #0

    copy:

        ldrb r3, [r0, r2] @ load char from word

        cmp r3, #0 @ if zero

        beq endCopy @ end copy

        mov r3, #'_' @ load underscore

        strb r3, [r1, r2] @ save in current word

        add r2, r2, #1 @ increment position

        b copy @ repeat

    endCopy:

        strb r3, [r1, r2] @ save zero in current word

        bx lr

    @ search the letter r0 in the word at r1,

    @ returns 0 if not found, non zero otherwise

    .global searchLetter

    .type searchLetter, %function

    searchLetter:

        mov r2, #0 @ start index in zero

    srchLoop:

        ldrb r3, [r1, r2] @ load character from string

        cmp r3, #0 @ if end of string

        beq notfound @ go to not found

        cmp r3, r0 @ if it's the searched letter

        beq found @ return found

        add r2, r2, #1 @ advance to next char

        b srchLoop @ search again

    notfound:

        mov r0, r3 @ return zero

    found:

        bx lr

    @ uncover all letters equal to r0 in the current word r1 using the word in r2

    .global uncoverLetters

    .type uncoverLetters, %function

    uncoverLetters:

        push {r4}

        mov r3, #0 @ start at index 0

    uncoverLoop:

        ldrb r4, [r2, r3] @ load letter from word

        cmp r4, #0 @ if end of word

        beq uncoverEnd @ end uncovering

        cmp r4, r0 @ see if it's searched letter

        bne unconverNext @ if not, go to next

        strb r4, [r1, r3] @ else, uncover letter

    unconverNext:

        add r3, r3, #1 @ increment position

        b uncoverLoop @ repeat loop

    uncoverEnd:

        pop {r4}

        bx lr

    @ see if the two strings in r0 and r1 are equal, returns 0 if equal, not zero if not

    .global strEqual

    .type strEqual, %function

    strEqual:

        push {r4}

        mov r2, #0 @ start at index 0

    cmpLoop:

        ldrb r3, [r0, r2] @ load letter from first word

        ldrb r4, [r1, r2] @ load letter from second word

        subs r3, r3, r4 @ see if they are equal

        bne cmpEnd @ if not equal, end

        cmp r4, #0 @ else, if end of word

        beq cmpEnd @ end, they are equal

        add r2, r2, #1 @ else, increment position

        b cmpLoop @ repeat loop

    cmpEnd:

        mov r0, r3 @ return last comparison

        pop {r4}

        bx lr

    @ division of r0 over r1 using repeated subtractions, returns quotient in r0,

    @ remainder in r1

    .global div

    .type div, %function

    div:

        mov r2, r1 @ copy divisor to r2

        mov r1, r0 @ copy dividend to r1

        mov r0, #0 @ quotient = 0

    divLoop:

        subs r3, r1, r2 @ subtract divisor

        blt divEnd @ if negative, end

        mov r1, r3 @ else, update number

        add r0, r0, #1 @ increment quotient

        b divLoop

    divEnd:

        bx lr @ return

    @ read a character

    readChar:

        push {r4, fp, lr}

        bl getchar @ read letter

        mov r4, r0 @ save read char

    getNL:

        bl getchar @ read until the '\n'

        cmp r0, #10

        bne getNL

        mov r0, r4 @ return first char

        pop {r4, fp, lr}

        bx lr