LC-3 Assembly Language Nim Game

@_@Assembly T_T

Table of contents

Topic description

AC code

Thought analysis


Topic description

Nim is a simple two-player game that probably originated in China. There are many types of counters used in the game, such as stones, matches, apples, etc. The game interface is divided into many lines, each with a different number of counters:

line number

Number of counters

1

○○○

2

○○○○○○

...

...

n

○○○○○○○○○○

This experiment made some small changes to the Nim game, as follows: the game interface consists of three lines, and the counter type is stone, of which row A contains 3 stones, row B contains 5 stones, and row C contains 8 stones.

The rules are as follows:

⑴ Each player takes turns removing one or more stones from a row.

⑵ A player cannot remove stones from more than one row in one turn.

(3) When a player removes the last remaining stones from the game interface, the game ends and the player wins.

Require

⑴ At the beginning of the game, you should display the initialization state of the game interface. Specifically: In front of each row of stones, you should output the name of the row, such as "ROW A". You should use the ASCII character lowercase "o" (ASCII code x006F) to represent the stone. The initial state of the game interface should be as follows:

ROW A: ooo

ROW B: ooooo

ROW C: oooooooo

(2) The game always starts with player 1 first, then player 1 and player 2 take turns. At the beginning of each turn, you should output which player's turn it is to start, and prompt the player to take action. For example, for player 1, the following should appear:

Player 1,choose a row and number of rocks:

(3) In order to specify how many stones in a row to remove, the player should enter a letter followed by a number (no need to press Enter after typing), where the letter (A, B or C) specifies the row and the number (from 1 to Number of Stones in Selected Row) specifies the number of stones to remove. Your program must ensure that the player removes a valid number of stones from a valid row. If the player's input is invalid, you should output an error message and prompt the player to enter again. For example, if it's Player 1's turn:

Player 1, choose a row and number of rocks: D4

Invalid move. Try again.

Player 1, choose a row and number of rocks: A9

Invalid move. Try again.

Player 1, choose a row and number of rocks: A*

Invalid move. Try again.

Player 1, choose a row and number of rocks: &4

Invalid move. Try again.

Player 1, choose a row and number of rocks:

Your program should keep prompting the player until the player selects a valid input. Make sure your program can echo the player's input to the screen. When echoing the player's input, it should output a newline character (ASCII code x000A) to point the cursor to the next line.

⑷ After the player selects a valid input, you should check the winner. If a player wins, you should display the corresponding output to indicate that player wins. If there is no winner, your program should update the number of stones per row in the game screen, redisplay the updated game screen, and move on to the next player's turn.

⑸ When a player removes the last stone from the game interface, the game ends. At this point, your program should display the winner and stop. For example, if player 2 removes the last stone, your program should output the following:

Player 2 Wins.

Sample input/output

ROW A: ooo
ROW B: ooooo
ROW C: oooooooo
Player 1, choose a row and number of rocks: B2
ROW A: ooo
ROW B: ooo
ROW C: oooooooo
Player 2, choose a row and number of rocks: A1
ROW A: oo
ROW B: ooo
ROW C: oooooooo
Player 1, choose a row and number of rocks: C6
ROW A: oo
ROW B: ooo
ROW C: Oh
Player 2, choose a row and number of rocks: G1
Invalid move. Try again.
Player 2, choose a row and number of rocks: B3
ROW A: oo
ROW B: 
ROW C: Oh
Player 1, choose a row and number of rocks: A3
Invalid move. Try again.
Player 1, choose a row and number of rocks: C2
ROW A: oo
ROW B:
ROW C: 
Player 2, choose a row and number of rocks: A1
ROW A: o
ROW B:
ROW C:
Player 1, choose a row and number of rocks: A*
Invalid move. Try again.
Player 1, choose a row and number of rocks: &4
Invalid move. Try again.
Player 1, choose a row and number of rocks: A1
Player 1 Wins.
----- Halting the processor ----- 

Tips and Advice

⑴ Remember, all input and output in the program use ASCII characters, you should be responsible for the necessary conversion.

(2) To input characters from the keyboard you should use the TRAP x20 (GETC) command, and in order to echo the typed characters to the screen, you should use the TRAP x21 (OUT) command, which follows the TRAP x20 command.

(3) You should use subroutines when appropriate.

⑷ In each subroutine you write, you should save and restore any registers you use. This will avoid you having problems during debugging.

⑸ During a turn, the player's input must consist of a line designated A, B or C (i.e. capital letters) followed by a number not greater than the number of stones still present in that line.

hint:

① You should set the start address of the program at x3000 (for example, the first line of the program should be .ORIG x3000)

② The source file is named nim.asm

AC code

	.orig x3000

again	jsr print
	jsr datain1
	jsr print
	jsr datain2
	br again


print	st r0,save_r0
	st r1,save_r1
	st r7,save_r7
	lea r0,row_a
	puts
	ld r0,stone
	ld r1,num_a
loop_a	out
	add r1,r1,#-1
	brp loop_a
	ld r0,cr
	out
	lea r0,row_b
	puts
	ld r0,stone
	ld r1,num_b
loop_b	out
	add r1,r1,#-1
	brp loop_b
	ld r0,cr
	out
	lea r0,row_c
	puts
	ld r0,stone
	ld r1,num_c
loop_c	out
	add r1,r1,#-1
	brp loop_c
	ld r0,cr
	out
	ld r0,save_r0
	ld r1,save_r1
	ld r7,save_r7
	ret

save_r0 .fill #0
save_r1 .fill #0
stone 	.fill x006f
cr	.fill x000d
row_a	.stringz "ROW A: "
row_b	.stringz "ROW B: "
row_c	.stringz "ROW C: "
num_a	.fill #3
num_b	.fill #5
num_c	.fill #8


cue1	st r0,save_r0
	st r7,save_r7
	lea r0,play1
	puts
	ld r0,save_r0
	ld r7,save_r7
	ret
play1	.stringz "Player 1,choose a row and number of rocks:"


cue2	st r0,save_r0
	st r7,save_r7
	lea r0,play2
	puts
	ld r0,save_r0
	ld r7,save_r7
	ret
play2	.stringz "Player 2,choose a row and number of rocks:"
save_r7 .fill #0


datain1	st r0,save_r0
	st r2,save_r2
	st r3,save_r3
	st r7,saver7
try1	jsr cue1
	getc
	out
	add r2,r0,#0
	not r2,r2
	add r2,r2,#1
	getc
	out
	add r3,r0,#0
	ld r0,lf
	out
test1a	ld r0,char_a
	add r0,r2,r0
	brnp test1b
	ld r0,char_0
	not r0,r0
	add r0,r0,#1
	add r0,r0,r3
	brn error1
	ld r3,num_a
	not r0,r0
	add r0,r0,#1
	add r3,r0,r3
	brn error1
	st r3,num_a
	ld r3,sum_abc
	add r3,r3,r0
	brz win1
	st r3,sum_abc
	br save
test1b	ld r0,char_b
	add r0,r2,r0
	brnp test1c
	ld r0,char_0
	not r0,r0
	add r0,r0,#1
	add r0,r0,r3
	brn error1
	ld r3,num_b
	not r0,r0
	add r0,r0,#1
	add r3,r0,r3
	brn error1
	st r3,num_b
	ld r3,sum_abc
	add r3,r3,r0
	brz win1
	st r3,sum_abc
	br save
test1c	ld r0,char_c
	add r0,r2,r0
	brnp error1
	ld r0,char_0
	not r0,r0
	add r0,r0,#1
	add r0,r0,r3
	brn error1
	ld r3,num_c
	not r0,r0
	add r0,r0,#1
	add r3,r0,r3
	brn error1
	st r3,num_c
	ld r3,sum_abc
	add r3,r3,r0
	brz win1
	st r3,sum_abc
	br save		
win1	ld r0,lf
	out
	lea r0,wins1
	puts	
	halt
error1	lea r0,invalid
	puts
	ld r0,lf
	out
	br try1

datain2	st r0,save_r0
	st r2,save_r2
	st r3,save_r3
	st r7,saver7
try2	jsr cue2
	getc
	out
	add r2,r0,#0
	not r2,r2
	add r2,r2,#1
	getc
	out
	add r3,r0,#0
	ld r0,lf
	out
test2a	ld r0,char_a
	add r0,r2,r0
	brnp test2b
	ld r0,char_0
	not r0,r0
	add r0,r0,#1
	add r0,r0,r3
	brn error2
	ld r3,num_a
	not r0,r0
	add r0,r0,#1
	add r3,r0,r3
	brn error2
	st r3,num_a
	ld r3,sum_abc
	add r3,r3,r0
	brz win2
	st r3,sum_abc
	br save
test2b	ld r0,char_b
	add r0,r2,r0
	brnp test2c
	ld r0,char_0
	not r0,r0
	add r0,r0,#1
	add r0,r0,r3
	brn error2
	ld r3,num_b
	not r0,r0
	add r0,r0,#1
	add r3,r0,r3
	brn error2
	st r3,num_b
	ld r3,sum_abc
	add r3,r3,r0
	brz win2
	st r3,sum_abc
	br save
test2c	ld r0,char_c
	add r0,r2,r0
	brnp error2
	ld r0,char_0
	not r0,r0
	add r0,r0,#1
	add r0,r0,r3
	brn error2
	ld r3,num_c
	not r0,r0
	add r0,r0,#1
	add r3,r0,r3
	brn error2
	st r3,num_c
	ld r3,sum_abc
	add r3,r3,r0
	brz win2
	st r3,sum_abc
	br save	
	
win2	ld r0,lf
	out
	lea r0,wins2
	puts	
	halt
error2	lea r0,invalid
	puts
	ld r0,lf
	out
	br try2
save	ld r0,lf
	out	
	ld r0,saver0
	ld r2,save_r2
	ld r3,save_r3
	ld r7,saver7
	ret

lf	.fill x000a
char_a	.fill x0041
char_b	.fill x0042
char_c	.fill x0043
char_0	.fill x0030
wins1	.stringz "Player 1 Wins."
wins2	.stringz "Player 2 Wins."
invalid	.stringz "Invalid move. Try again."
sum_abc	.fill #16
saver0	.fill #0
save_r2 .fill #0
save_r3 .fill #0
saver7	.fill #0
	.end

Thought analysis

overall program design

core data structure

1. Display the game page

First store the value of the register into the memory, and then store the value of the memory into the register after the sub-function completes the task, use the pseudo operation .stringz to open up memory to store strings, and set the number of stones in Row A, Row B and Row C Also stored in memory.

First use the LEA instruction to store the first address of the string into R0, then output it through PUTS, use the LD instruction to store the ascll code of the character o into R0, and then use the LD instruction to store the number of stones into R1, R1 as a counter, use OUT The character o is output in a loop, and finally the ascll code of the newline character is stored in R0 with the LD instruction, and output with OUT.

2. User operation

(1) Output prompt

Use the pseudo operation .stringz to store the prompt string in the memory, first store the values ​​of the registers R0 and R7 used in the memory, and then use the LEA instruction to store the first address of the string in R0, and use PUTS to output the prompt, Then restore the values ​​of R0 and R7.

(2) User input

    Use GETC to read the first input data, and then use OUT to echo, ADD command to transfer the data of R0 into R2, then use NOT to invert R2, ADD adds one to R2, that is, negative R2, and then use GETC to read Take the second input data, OUT echoes it, and the ADD instruction transfers the data of R0 into R3.

(3) Determine whether the data is valid

    Use the pseudo operation .fill to store the ascll codes of characters A, B and C into the memory, use the LD instruction to store the ascll codes of the corresponding characters into R0, and then use the ADD instruction to add the result of R0 and R2 to R0, by judging whether R0 is It is 0 to judge whether it is A, B, C or invalid input.

(4) Take the stone

    Use the LD instruction to store the ascll code of character 0 into R0, then negate R0, and store the result of the addition with R3 into R0, then use the LD instruction to store the number of stones into R3, negate R0, and compare with R3. The result of the addition is stored in R3, and finally the value of R3 is stored in the memory.

Algorithm flow

1. Display the game page

2. Player operation

 

 

Guess you like

Origin blog.csdn.net/weixin_62264287/article/details/126391351