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
- 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.
- The player has six chances to guess the letters for each game.
- Valid inputs of the game are from A-Z or a-z (convert the letter into a capital if a small letter is input).
- For each correct letter guessed, the letter is revealed at its correct location or locations in the word.
- For each incorrect letter guessed, an additional segment of the stick figure "hangman" is displayed.
- The stick figure has 6 segments in total: head, body, left and right arms, and left and right legs.
- The game is won when the entire word is guessed.
- The game is lost when the entire hangman is displayed.
- The game is exited upon winning, losing, or the player entering the 0 (zero) character.
- When the game is finished, the player can choose to have another round.
- 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
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
Similar Samples
Discover the quality of our work through these detailed samples. Each example showcases our expertise in various programming languages and problem-solving skills. Whether you're looking for assistance in Python, Java, C++, or any other programming language, our samples highlight the precision and proficiency you can expect from our services.
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language
Assembly Language