8086汇编石头剪刀布游戏:电脑选择无法随机变更的问题求助
问题分析与解决方案
核心问题
- 随机数生成逻辑错误:原
RANDOMIZE函数错误处理了DOS时间中断的返回值,导致无法基于时间变化生成新的随机数。 - 重复调用随机函数:每次游戏循环中同时调用
RANDOMIZE和COMPUTER_CHOICE(后者内部再次调用RANDOMIZE),造成冗余的随机数生成操作。
修正后的代码
.MODEL SMALL .STACK 100H .DATA playerChoice DB ? computerChoice DB ? userInput DB 'ROCK PAPER SCISSORS? (1-Rock 2-Paper 3-Scissors q-Quit) : $' playerWinsMsg DB 'Result : Player Won! $' computerWinsMsg DB 'Result : Computer Won! $' tieMsg DB 'Result : Tie!! $' invalidChoiceMsg DB 'Invalid choice! Try again!! $' .CODE MAIN PROC MOV AX, @DATA MOV DS, AX GAME_LOOP: MOV AH, 09H LEA DX, userInput INT 21H MOV AH, 01H INT 21H CMP AL, 'q' JE EXIT SUB AL, 30H MOV playerChoice, AL MOV AH,2 MOV DL, 10 INT 21H MOV DL, 13 INT 21H ; 只调用一次随机函数即可,去掉重复调用 CALL RANDOMIZE CMP playerChoice, 1 JE ROCK CMP playerChoice, 2 JE PAPER CMP playerChoice, 3 JE SCISSORS LEA DX, invalidChoiceMsg MOV AH, 09H INT 21H MOV AH,2 MOV DL, 10 INT 21H MOV DL, 13 INT 21H JMP GAME_LOOP ROCK: CMP computerChoice, 1 JE TIE CMP computerChoice, 2 JE COMPUTER_WINS CMP computerChoice, 3 JE PLAYER_WINS JMP EXIT PAPER: CMP computerChoice, 1 JE PLAYER_WINS CMP computerChoice, 2 JE TIE CMP computerChoice, 3 JE COMPUTER_WINS JMP EXIT SCISSORS: CMP computerChoice, 1 JE COMPUTER_WINS CMP computerChoice, 2 JE PLAYER_WINS CMP computerChoice, 3 JE TIE JMP EXIT PLAYER_WINS: MOV AH, 09H LEA DX, playerWinsMsg INT 21H MOV AH,2 MOV DL, 10 INT 21H MOV DL, 13 INT 21H JMP GAME_LOOP COMPUTER_WINS: MOV AH, 09H LEA DX, computerWinsMsg INT 21H MOV AH,2 MOV DL, 10 INT 21H MOV DL, 13 INT 21H JMP GAME_LOOP TIE: MOV AH, 09H LEA DX, tieMsg INT 21H MOV AH,2 MOV DL, 10 INT 21H MOV DL, 13 INT 21H JMP GAME_LOOP ; 修正后的随机数生成函数 RANDOMIZE: MOV AH, 2CH ; DOS中断21H/2CH:获取系统时间 INT 21H ; 返回值:CH=小时, CL=分钟, DH=秒, DL=百分秒(0-99) MOV AL, DL ; 取百分秒作为随机种子(数值随时间变化) XOR AH, AH ; 将AX清零高8位,AX = 0000H + DL(0-99) MOV BL, 3 ; 除数为3,用于生成0-2的余数 DIV BL ; 除法操作:AL=商,AH=余数(0、1、2) MOV AL, AH ; 取余数作为基础值 ADD AL, 1 ; 将余数转为1-3的范围 MOV computerChoice, AL RET ; 可选:如果保留此函数,内部调用RANDOMIZE即可,但无需在主循环重复调用 COMPUTER_CHOICE: CALL RANDOMIZE RET EXIT: MOV AH, 4CH INT 21H MAIN ENDP END MAIN
关键修正点
- 修复随机数生成逻辑:正确使用DOS时间中断返回的
DL(百分秒)作为随机种子,通过模3运算得到0-2的余数,再加1转为1-3的有效选择范围。 - 移除重复调用:主循环中只调用一次
RANDOMIZE(或COMPUTER_CHOICE),避免重复生成随机数导致的不必要覆盖。
内容的提问来源于stack exchange,提问作者canerkaraca
相关产品推荐
相关产品推荐

