CS计算机代考程序代写 data structure Java gui .data

.data
title: .asciiz “COMP2611 Gold Miner Game”
game_win: .asciiz “You Win! Enjoy the game brought by COMP2611!”
game_lose: .asciiz “You are fired!”

width: .word 800 # the width of the screen
height: .word 600 # the height of the screen

level_title: .asciiz “Level:”
max_level: .word 3 # the level limit is 3
game_level: .word 1 # level of the game, initilized to be 1
level_time_limit:.word 90000 # the time limit of level in ms
level_timer: .word 0 # the timer of level in ms
level_start: .word 0 # the starting time of level
level_quota: .word 0 # the quota of level
level_balance: .word 0 # the balance of level

mineral_ids: .word -1:200 # used to keep track of the ids of minerals
mineral_locs: .word -1:400 # the array of initialized locations of minerals
mineral_sizes: .word -1:400 # the array of sizes of minerals
mineral_base: .word 2 # base id of minerals
mineral_num: .word 0 # the number of minerals
gold_num: .word 0 # the number of gold
gem_num: .word 0 # the number of gem
rock_num: .word 0 # the number of rock

dynamite_ids: .word -1:30 # used to keep track of the ids of dynamites
dynamite_base: .word 60 # base id of the dynamite
dynamite_num: .word 0 # the number of dynamites
dynamite_remain:.word 0 # the number of remaining dynamites

.text
main: # Create the Game Screen
li $v0, 100
la $a0, title
la $t0, width
lw $a1, 0($t0)
la $t0, height
lw $a2, 0($t0)
syscall
# play the background music
li $v0, 102
li $a0, 0
li $a1, 1
syscall

game_level_init:# Set the parameters for the game level
# set game level
li $v0, 103
li $a0, 0
la $t0, game_level
lw $a1, 0($t0)
syscall
# Set level timer
li $v0, 103
li $a0, 1
la $t0, level_time_limit
lw $a1, 0($t0)
addi $a1, $a1, -15000 # ms
sw $a1, 0($t0)
syscall
# Set level quota
li $v0, 103
li $a0, 2
la $t0, level_quota
lw $a1, 0($t0)
addi $a1, $a1, 2000
sw $a1, 0($t0)
syscall
# Set level balance
li $v0, 103
li $a0, 3
la $t0, level_balance
sw $zero, 0($t0)
li $a1, 0
syscall
# Gold number increase by 3
la $t0, gold_num
lw $t1, 0($t0)
addi $t1, $t1, 3
sw $t1, 0($t0)
# Gem number increase by 2
la $t0, gem_num
lw $t1, 0($t0)
addi $t1, $t1, 2
sw $t1, 0($t0)
# Rock number increase by 4
la $t0, rock_num
lw $t1, 0($t0)
addi $t1, $t1, 4
sw $t1, 0($t0)
# Available dynamites set to level
la $t0, dynamite_num
la $t1, game_level
lw $t1, 0($t1)
sw $t1, 0($t0)
# Get level starting time
jal get_time
la $t0, level_start
sw $v0, 0($t0)

game_start: # Initialize the game by create Game Objects based on game level
jal init_game

main_loop: jal get_time
add $s6, $v0, $zero # $s6: starting time of the game
jal update_timer
jal check_game_status # task 6
bne $v0, $zero, game_end_status
jal update_hook_status # task 2, 3
jal update_minteral_status # task 4
jal update_dynamite_status # task 5
jal process_input
jal move_hook # task 1
jal move_minerals
jal move_dynamites
# refresh screen
li $v0, 101
syscall
add $a0, $s6, $zero
li $a1, 30 # iteration gap: 30 milliseconds
jal have_a_nap
j main_loop

game_end_status:# $v0 hold the game status of current level, $v0 = 1 win, $v0 = 2 lose
li $t0, 2 # $t0 = 2
beq $v0, $t0, game_over # game over if lose in any level
# the following handles win at any level
la $t0, game_level
lw $t1, 0($t0) # $t1 = current game level
la $t0, max_level
lw $t2, 0($t0) # $t2 = max_level
beq $t1, $t2, win # winning at max level means winning the game
# if the winning level is lower than max_level, promote to the next level
addi $t1, $t1, 1
la $t0, game_level
sw $t1, 0($t0) # promote to next level
# destroy all minerals and dynamites in last level
jal destroy_minerals
jal destroy_dynamites
# start game next level
j game_level_init
game_over: li $v0, 106 # create game lose text
li $a0, -1 # special id for lose_text
li $a1, 300
li $a2, 300
la $a3, game_lose
syscall
li $v0, 101 # refresh screen
syscall
li $v0, 102 # play lose sound
li $a0, 2
li $a1, 0
syscall
j game_pause
win: li $v0, 106 # game win text
addi $a0, $zero, -2 # special id for win_text
addi $a1, $zero, 80
addi $a2, $zero, 280
la $a3, game_win
syscall
li $v0, 101 # refresh screen
syscall
li $v0, 102 # play win sound
li $a0, 1
li $a1, 0
syscall
game_pause: add $a0, $s6, $zero
addi $a1, $zero, 600
jal have_a_nap # count 10 mins from start
li $v0, 10 # exit
syscall

#——————————————————————–
# func: init_game (num_gold, num_gem, num_rock, num_dynamite)
# 1. create the hook: located at the point (389, 100)
# 2. create minerals;
# 3. init the ids for dynamite
#——————————————————————–
init_game: # preserve stack
addi $sp, $sp, -28
sw $ra, 24($sp)
sw $s0, 20($sp)
sw $s1, 16($sp)
sw $s2, 12($sp)
sw $s3, 8($sp)
sw $s4, 4($sp)
sw $s5, 0($sp)
# 1. create the hook
li $v0, 105
li $a0, 1 # the id of hook is 1
li $a1, 0 # hook type
li $a2, 389 # the x_loc of hook
li $a3, 100 # the y_loc of hook
syscall
li $v0, 112 # set hook’s speed
li $a0, 1 # hook’s id
li $a1, 12 # the speed of hook
syscall
# 2. create the specified number of minerals
# 2.1 Gold
la $t0, gold_num
lw $a0, 0($t0) # the count of required mineral
# ———————————————-
# since the game image is not really rectanglar,
# you can set the size to be smaller for greater
# the sense of impact (challenge mode!!!). However,
# this does not change the actual image size because
# GUI is handled in Java. This affects the collision
# checks. Same applies for all other minerals.
# ———————————————-
li $a1, 1 # the mineral type
li $s2, 60 # the image width by default, more challenging if set to 50
li $s3, 45 # the image height by default, more challenging if set to 35
li $s4, 6 # the speed
li $s5, 500 # the price
jal create_multi_minerals
# 2.2 Gem
la $t0, gem_num
lw $a0, 0($t0)
li $a1, 2
li $s2, 30
li $s3, 18
li $s4, 9
li $s5, 1500
jal create_multi_minerals
# 2.3 Rock
la $t0, rock_num
lw $a0, 0($t0)
li $a1, 3
li $s2, 100
li $s3, 75
li $s4, 3
li $s5, 0
jal create_multi_minerals
# 3. init dynamites
la $t0, dynamite_num
lw $a0, 0($t0)
li $a1, 4
jal init_dynamite
# refresh screen
li $v0, 101
syscall
ig_exit: # restore stack
lw $ra, 24($sp)
lw $s0, 20($sp)
lw $s1, 16($sp)
lw $s2, 12($sp)
lw $s3, 8($sp)
lw $s4, 4($sp)
lw $s5, 0($sp)
addi $sp, $sp, 28
jr $ra

#——————————————————————–
# func create_multi_Minerals(total_num, created_num)
# @total_num: the number of Minerals needs to be created
# @created_num: the number of Minerals previously created
# Some attributes are passed through stack
# $s2: width
# $s3: height
# $s4: speed
# $s5: price
# Create multiple Minerals on the Game Screen.
#——————————————————————–
create_multi_minerals:
addi $sp, $sp, -16
sw $ra, 12($sp)
sw $s0, 8($sp)
sw $s1, 4($sp)
sw $s6, 0($sp)
add $s0, $a0, $zero # $s0: total required creation num
la $t0, mineral_num
lw $s1, 0($t0) # $s1: created num
add $s6, $a1, $zero # $s6: the mineral type
cmm_loop: beq $s0, $zero, cmm_exit # if total = 0, finish creation
# calculate id
la $t0, mineral_base
lw $t1, 0($t0)
add $a0, $t1, $s1 # id = base + created_num
# get the allocated grid for mineral’s location
# it returns [-1, -1] if there exists 46 minerals in the cave already
li $v0, 104
syscall
add $a1, $s6, $zero # mineral type
add $a2, $v0, $zero # xLoc
add $a3, $v1, $zero # yLoc
# before syscall, store (id, x_loc, y_loc, width, height) into arrays
la $t0, mineral_ids
sll $t1, $s1, 2
add $t1, $t1, $t0
sw $a0, 0($t1) # save id
la $t0, mineral_locs
sll $t1, $s1, 3
add $t1, $t1, $t0
sw $a2, 0($t1) # save x_loc
sw $a3, 4($t1) # save y_loc
la $t0, mineral_sizes
sll $t1, $s1, 3
add $t1, $t1, $t0
sw $s2, 0($t1) # save width
sw $s3, 4($t1) # save height
# create object mineral
li $v0, 105
syscall
# set speed
li $v0, 112
add $a1, $s4, $zero
syscall
# set price
li $v0, 117
add $a1, $s5, $zero
syscall
addi $s1, $s1, 1 # created_num++
subi $s0, $s0, 1 # total_num–
j cmm_loop
cmm_exit: # accumulate the created minerals
la $t0, mineral_num
sw $s1, 0($t0)
lw $ra, 12($sp)
lw $s0, 8($sp)
lw $s1, 4($sp)
lw $s2, 0($sp)
addi $sp, $sp, 16
jr $ra

#——————————————————————–
# func init_dynamite(num_dynamites)
# Initialize the “data structure” for dynamites:
# dynamite_num = @num_dynamites, dynamite_count = 0, dynamite_ids[:dynamite_num] = 0;
#——————————————————————–
init_dynamite: addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
add $s0, $a0, $zero # $s0 = num_dynamites
# update available dynamites
li $v0, 103
li $a0, 4
add $a1, $s0, $zero
syscall
la $t0, dynamite_remain # dynamite_remain = dynamite_num
sw $s0, 0($t0)
la $s1, dynamite_ids # $s1: the dynamite id array
ind_loop: beq $s0, $zero, ind_exit # loop if dynamite_num > 0
addi $s0, $s0, -1 # i–
sll $t0, $s0, 2
add $t0, $t0, $s1 # the address of dynamite_ids[i] = &dynamite_ids[0] + i
sw $zero, 0($t0) # dynamite_ids[i] = 0, which indicates non-existence
j ind_loop
ind_exit: lw $ra, 8($sp)
lw $s0, 4($sp)
lw $s1, 0($sp)
addi $sp, $sp, 12
jr $ra

#——————————————————————–
# func update_timer
# Update the level timer on screen.
# Since the sleep function severely distorts time calculation,
# here we use the starting time of level as the basis to calculate time passed.
#——————————————————————–
update_timer: addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
jal get_time
la $t0, level_start
lw $t0, 0($t0) # $t0: the level’s starting time
sub $s0, $v0, $t0 # $s0: time passed = now’s time – level’s starting time
la $t1, level_time_limit
lw $s1, 0($t1) # $s1: the level’s time limit
sub $a1, $s1, $s0 # timer = time limit – time passed
la $t0, level_timer
sw $a1, 0($t0) # save the timer
li $v0, 103
li $a0, 1
syscall
lw $ra, 8($sp)
lw $s0, 4($sp)
lw $s1, 0($sp)
addi $sp, $sp, 12
jr $ra

#——————————————————————–
# func: check_game_status
# Check whether the game is over!
# 1. player wins the game when the balance >= quota
# 2. player loses the game when the timer <= 0 # @return: $v0={0: not end; # 1: win; # 2: lose #-------------------------------------------------------------------- check_game_status: # =================================== TODO ========================================== # Task6: check_game_status # Check whether the game should continue, has been won, or has been lost. # ============================= You codes start here ================================ li $v0, 0 jr $ra # ============================= Your codes end here ================================= #-------------------------------------------------------------------- # func update_hook_status # Check and change the status of the hook according to these conditions: # 1. if the hook goes beyong the screen, it should start rewinding; # 2. if the hook reaches the winch, its status should be reset to start rotating; #-------------------------------------------------------------------- update_hook_status: addi $sp, $sp, -8 sw $ra, 4($sp) sw $s0, 0($sp) # check hook's condition li $v0, 108 # get hook's location li $a0, 1 # hook's id syscall # if it goes beyond screen sge $t0, $v0, 850 # if the hook's x_loc >= 850
sle $t1, $v0, -50 # if the hook’s x_loc <= -50 sge $t2, $v1, 650 # if the hook's y_loc >= 650
sle $t3, $v1, 0 # if the hook’s y_loc <= 0 or $t0, $t0, $t1 or $t0, $t0, $t2 or $t0, $t0, $t3 bne $t0, $zero, uhs_rewind # any true condition leads to rewind # if it is hooked and reaches the winch sle $t0, $v1, 80 # if the hook's y_loc <= 80, i.e. the horizontal line where the winch locates beq $t0, $zero, uhs_exit # if hook has not reached the winch li $v0, 118 # get isHooked syscall beq $v0, $zero, uhs_exit # if hook is not hooked => the special case whrere the swinging is not implemented
uhs_rotate: # if the hook has reached the winch when it is hooked (either a mineral or the boundaries)
li $v0, 119 # toggle isHooked to stop the hook from rewinding
syscall
li $v0, 121 # toggle isShoot to start hook’s rotation
syscall
li $v0, 109 # reset hook’s location
li $a1, 389 # the x_loc of hook
li $a2, 100 # the y_loc of hook
syscall
li $v0, 112 # reset hook’s speed
li $a1, 12 # the speed of hook
syscall
li $v0, 114 # reset hook’s direction
li $a1, 0 # the direction of hook
syscall
j uhs_exit
uhs_rewind: li $v0, 119 # toggle isHooked to let the hook rewind
syscall
uhs_exit: lw $ra, 4($sp)
lw $s0, 0($sp)
addi $sp, $sp, 8
jr $ra

#——————————————————————–
# func update_minteral_status
# Check and change the status of the minerals according to these conditions:
# 1. if a mineral is not hooked
# 1.1 if the hook is already attached with something, do nothing;
# 1.2 if it intersects with the hook, attach it to the hook;
# 2. if a mineral is hooked
# 2.1 if it reaches the winch, cash in and destroy;
#——————————————————————–
update_minteral_status: # check minerals’ condition
addi $sp, $sp, -20
sw $ra, 16($sp)
sw $s0, 12($sp)
sw $s1, 8($sp)
sw $s2, 4($sp)
sw $s3, 0($sp)
la $t0, mineral_num
lw $s0, 0($t0) # $s0: the number of minerals
la $s1, mineral_ids # $s1: the id array
ums_loop: beq $s0, $zero, ums_exit # if all minerals are checked
addi $t0, $s0, -1 # i = n – 1
sll $t0, $t0, 2
add $s2, $s1, $t0 # $s2: the address that stores the mineral’s id
lw $s3, 0($s2) # $s3: the id of the mineral
beq $s3, $zero, ums_next # this mineral has already been sold
# check if it is hooked
li $v0, 118
add $a0, $s3, $zero
syscall
bne $v0, $zero, ums_hooked # if this mineral is hooked
ums_unhooked: # check if this unhooked mineral intersects with the hook
# but the hook must not attach to other minerals
li $v0, 118 # get hook’s isHooked
li $a0, 1
syscall
bne $v0, $zero, ums_next # the hook has hooked to something else
addi $a0, $s0, -1 # mineral’s index
jal check_hook_hit
beq $v0, $zero, ums_next # if the mineral does not intersect, check next
ums_intersect: # if the two intesect
# handle isHooked
li $v0, 119 # toggle isHooked
add $a0, $s3, $zero # for the mineral
syscall
li $v0, 119 # toggle isHooked
li $a0, 1 # for the hook
syscall
# align location
li $v0, 108 # get hook’s location
li $a0, 1
syscall
add $a0, $s3, $zero
add $a1, $v0, $zero
add $a2, $v1, $zero
li $v0, 109 # set mineral’s location
syscall
# align direction
li $v0, 113 # get hook’s direction
li $a0, 1
syscall
add $a0, $s3, $zero
add $a1, $v0, $zero
li $v0, 114 # set mineral’s direction
syscall
# align speed
li $v0, 111 # get mineral’s speed
add $a0, $s3, $zero
syscall
li $a0, 1
add $a1, $v0, $zero
li $v0, 112 # set hook’s speed
syscall
# play hit sound
li $v0, 102
li $a0, 4
li $a1, 0
syscall
j ums_next
ums_hooked: # check if it reaches the winch
li $v0, 108 # get mineral’s location
add $a0, $s3, $zero
syscall
sle $t0, $v1, 80 # if the mineral’s y_loc <= 80 beq $t0, $zero, ums_next # if the mineral has not reached the winch, check next addi $a0, $s0, -1 # mineral's index # update level balance and destroy the mineral jal update_mineral_at_winch ums_next: addi $s0, $s0, -1 j ums_loop ums_exit: lw $ra, 16($sp) lw $s0, 12($sp) lw $s1, 8($sp) lw $s2, 4($sp) lw $s3, 0($sp) addi $sp, $sp, 20 jr $ra #-------------------------------------------------------------------- # func check_hook_hit(mineral_index) # Check whether the hook collides with the specified mineral. # @params: $a0: mineral_index # # @return: $v0={0: not intersected # 1: intersected #-------------------------------------------------------------------- check_hook_hit: # =================================== TODO ========================================== # Task3: check_hook_hit # This procedure pushes the coordinates of two game objects into the stack, # and then calls the procedure check_intersection implemented in task 2. # Hints: # You could reference the following procedure to help you complete: # get hook's location (hook's id is 1 by default) # read documentation to find hook's size # store hook's rect to stack # get mineral's location and size (reference create_multi_minerals) # store mineral's rect to stack # call check_intersection # reset stacks # ============================= You codes start here ================================ jr $ra # ============================= Your codes end here ================================= #-------------------------------------------------------------------- # func update_mineral_at_winch(mineral_index) # Given the mineral's id, update the level balance and destroy the object according. # @params: $a0: mineral_index #-------------------------------------------------------------------- update_mineral_at_winch: # =================================== TODO ========================================== # Task4: update_mineral_at_winch # This procedure manages the operations after the mineral has reached the winch. # They include updating level balance and destroying the mineral. # Hints: # You should destroy the object with syscall, and locate the mineral in the # mineral_ids array and set it 0 to remove it from game logic (see move_minerals). # The price of the mineral can be acquired from syscall. # ============================= You codes start here ================================ jr $ra # ============================= Your codes end here ================================= #-------------------------------------------------------------------- # func update_dynamite_status # Check and change the status of the dynamites according to these conditions: # 1. if the dynamite falls outside of the screen, it should be destroyed; # 2. if the dynamite hits a mineral, they should both be destroyed. #-------------------------------------------------------------------- update_dynamite_status: # check minerals' condition addi $sp, $sp, -16 sw $ra, 12($sp) sw $s0, 8($sp) sw $s1, 4($sp) sw $s2, 0($sp) la $t0, dynamite_num lw $s0, 0($t0) # $s0: the number of minerals la $s1, dynamite_ids # $s1: the id array uds_loop: beq $s0, $zero, uds_exit # if no available dynamites left addi $s0, $s0, -1 # dynamite_num-- sll $t0, $s0, 2 add $t0, $s1, $t0 # the address of dynamite_ids[i] = &dynamite_ids[0] + i lw $s2, 0($t0) # $s2: dynamite_ids[i] beq $s2, $zero, uds_loop # if dynamite_ids[i] == 0, the dynamite does not exist # check dynamite's location li $v0, 108 # get location add $a0, $s2, $zero syscall # if it goes beyond screen sge $t0, $v0, 850 # if the dynamite's x_loc >= 850
sle $t1, $v0, -50 # if the dynamite’s x_loc <= -50 sge $t2, $v1, 650 # if the dynamite's y_loc >= 650
sle $t3, $v1, -50 # if the dynamite’s y_loc <= -50 or $t0, $t0, $t1 or $t0, $t0, $t2 or $t0, $t0, $t3 bne $t0, $zero, uds_destroy # any true condition leads to destroy # check if dynamite intercepts with any minerals add $a0, $s2, $zero # dynamite_id jal check_dynamite_hit beq $v0, $zero, uds_loop # if the mineral does not intersect, check next # reset hook's speed because it is hooked to nothing now li $v0, 112 # set speed li $a0, 1 # hook's id li $a1, 12 # hook's speed by default syscall uds_destroy: li $v0, 107 # destroy dynamite add $a0, $s2, $zero syscall sll $t0, $s0, 2 add $t0, $s1, $t0 # the address of dynamite_ids[i] = &dynamite_ids[0] + i sw $zero, 0($t0) # dynamite_ids[i] = 0 j uds_loop uds_exit: lw $ra, 12($sp) lw $s0, 8($sp) lw $s1, 4($sp) lw $s2, 0($sp) addi $sp, $sp, 16 jr $ra #-------------------------------------------------------------------- # func check_dynamite_hit(dynamite_id) # Check whether the dynamite collides with any mineral. This procedure # loops over the minerals to call the procedure check_intersection for result. # @params: $a0: dynamite_id # # @return: $v0={0: not intersected # 1: intersected #-------------------------------------------------------------------- check_dynamite_hit: # =================================== TODO ========================================== # Task5: check_dynamite_hit # This procedure loops over the minerals to find any intersected minerals. # It pushes the coordinates of two game objects into the stack, # and then calls the procedure check_intersection implemented in task 2. # It should also destroy the intersected mineral before jumping back to return address. # Hints: # You could reference the following procedure to help you complete: # setup the loop conditions for all minerals # get dynamite's location # read documentation to find dynamite's size # store dynamite's rect to stack # get mineral's location and size (reference create_multi_minerals) # store mineral's rect to stack # call check_intersection # reset stacks # if they are not intersected, go to the next mineral or return # if they are intersected, destroy the mineral (as in task 4) and return with result. # ============================= You codes start here ================================ li $v0, 0 jr $ra # ============================= Your codes end here ================================= #-------------------------------------------------------------------- # func process_input # React to the keyboard input. #-------------------------------------------------------------------- process_input: addi $sp, $sp, -4 sw $ra, 0($sp) jal get_keyboard_input # $v0: the return value li $t0, 32 # corresponds to key 'space' beq $v0, $t0, pi_hook li $t0, 100 # corresponds to key 'd' beq $v0, $t0, pi_dynamite j pi_exit pi_dynamite: jal throw_dynamite j pi_exit pi_hook: jal shoot_hook j pi_exit pi_exit: lw $ra, 0($sp) addi $sp, $sp, 4 jr $ra #-------------------------------------------------------------------- # func shoot_hook # 1. toggle isShoot to stop rotation and start moving forward. # 2. if it isShoot is true, player cannot control it. #-------------------------------------------------------------------- shoot_hook: addi $sp, $sp, -4 sw $ra, 0($sp) li $v0, 120 # check isShoot li $a0, 1 # hook's id syscall bne $v0, $zero, shoot_hook_end # the hook is shoot li $v0, 121 #toggle isShoot syscall # play emit sound li $v0, 102 li $a0, 3 li $a1, 0 syscall shoot_hook_end: lw $ra, 0($sp) addi $sp, $sp, 4 jr $ra #-------------------------------------------------------------------- # func throw_dynamite # 1. check whether there are avaiable bombs to use. # 2. if yes, create one bomb object #-------------------------------------------------------------------- throw_dynamite: addi $sp, $sp, -20 sw $ra, 16($sp) sw $s0, 12($sp) sw $s1, 8($sp) sw $s2, 4($sp) sw $s3, 0($sp) la $t0, dynamite_remain lw $s0, 0($t0) # $s0: the remaining number of dynamites beq $s0, $zero, td_exit # if no remaining dynamites left # find the slot for a new dynamite la $t0, dynamite_num lw $s1, 0($t0) # $s1: the number of dynamites avilable in the level la $s2, dynamite_ids # $s2: the dynamites array's address td_loop: beq $s1, $zero, td_exit # if no available dynamites left addi $s1, $s1, -1 # dynamite_num-- sll $t0, $s1, 2 add $t0, $s2, $t0 # the address of dynamite_ids[i] = &dynamite_ids[0] + i lw $t1, 0($t0) # dynamite_ids[i] bne $t1, $zero, td_loop # if dynamite_ids[i] != 0, the dynamite exists # update available dynamites li $v0, 103 li $a0, 4 la $t0, dynamite_remain addi $s0, $s0, -1 # dynamite_remain-- sw $s0, 0($t0) # save it add $a1, $s0, $zero syscall # register the dynamite id la $t0, dynamite_base lw $s3, 0($t0) # $s3: the id value to be used add $s3, $s3, $s0 # id = base + remain_num sll $t0, $s1, 2 add $t0, $s2, $t0 # the address of dynamite_ids[i] = &dynamite_ids[0] + i sw $s3, 0($t0) # create a dynamite li $v0, 105 add $a0, $s3, $zero # the id li $a1, 4 li $a2, 400 # initial x_loc li $a3, 100 # initial y_loc syscall # set the speed li $v0, 112 li $a1, 15 syscall # set the direction li $v0, 113 # get hook's direction li $a0, 1 syscall add $a0, $s3, $zero add $a1, $v0, $zero li $v0, 114 # set mineral's direction syscall # play emit sound li $v0, 102 li $a0, 3 li $a1, 0 syscall td_exit: lw $ra, 16($sp) lw $s0, 12($sp) lw $s1, 8($sp) lw $s2, 4($sp) lw $s2, 0($sp) addi $sp, $sp, 20 jr $ra #-------------------------------------------------------------------- # func check_intersection(recA, recB) # @recA: ((x1, y1), (x2, y2)) # @recB: ((x3, y3), (x4, y4)) # these 8 parameters are passed through stack! # @params: the coordinates of RectA and RectB are passed through stack. # In total, 8 words are passed. RectA is followed by RectB, as shown below. # # | RectA.topleft_x | # | RectA.topleft_y | # | RectA.botrigt_x | # | RectA.botrigh_y | # | RectB.topleft_x | # | RectB.topleft_y | # | RectB.botrigt_x | # | RectB.botrigh_y | <-- $sp # # This function is to check whether the above two rectangles are intersected. # @return $v0=1: true(intersect with each other); 0: false #-------------------------------------------------------------------- check_intersection: # =================================== TODO ========================================== # Task2: check_intersection # This procedure checks whether the two input rectangles are intersected. # Notice that the coordinates are passed through the stack. # Hints: # Firstly, load 8 parameters/coordinates from the stack. # Secondly, check the conditions in which there could be no intersection: # condition1: whether recA's left edge is to the right of recB's right edge; # condition2: whether recA's right edge is to the left of recB's left edge; # condition3: whether recA's top edge is below recB's bottom edge; # condition4: whether recA's bottom edge is above recB's top edge. # Thirdly, set the value of $v0 based on the check result and jump to return address. # ============================= You codes start here ================================ li $v0, 0 jr $ra # ============================= Your codes end here ================================= #-------------------------------------------------------------------- # func: move_hook # Move the hook by one step. # # When the hook is not shoot: # It stays in the initial position and swing in different angle (change direction). # To swing in a pendulum, if the hook is going too far, make it move in the opposite direction. # i.e. if old_direction + swinging delta degree < -85degrees or old_direction + delta degree > 85degrees:
# change the moving direction
# When the hook is shoot:
# It stops swinging and move forward until it hits a mineral or the boundaries.
#——————————————————————–
move_hook: addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
li $v0, 120 # check isShoot
li $a0, 1 # id of hook
syscall
beq $v0, $zero, move_hook_swing # the hook is not shoot
li $v0, 110 # update location
li $a0, 1 # id of hook
syscall
j mh_exit
move_hook_swing:
# =================================== TODO ==========================================
# Task1: move_hook_swing
# This procedure moves the hook by changing its direction for one game iteration.
# To swing in a pendulum, the hook should stay between -85 to 85 degrees.
# Hints:
# You could utilize the isClockwise boolean variable to help decide the swinging direction.
# ============================= You codes start here ================================
# The following codes are the default behaviors, feel free to change them
li $v0, 115 # change direction
li $a0, 1 # id of hook
li $a1, -3 # swinging delta degree: -3 means clockwise movement
syscall
# ============================= Your codes end here =================================
mh_exit: lw $ra, 8($sp)
lw $s0, 4($sp)
lw $s1, 0($sp)
addi $sp, $sp, 12
jr $ra

#——————————————————————–
# func: move_minerals
# If a mineral is hooked, it starts to move along the hook back to the winch.
#——————————————————————–
move_minerals: addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
la $t0, mineral_num
lw $s0, 0($t0) # $s0: the number of minerals
mm_loop: beq $s0, $zero, mm_exit
la $s1, mineral_ids # $s1: unchanged till the end
addi $t0, $s0, -1 # mineral_num-1 to be the index
sll $t0, $t0, 2
add $t1, $s1, $t0 # $t1: the address of id
lw $a0, 0($t1) # $a0: the id of a mineral
beq $a0, $zero, mm_next # mineral_id equal 0 indicates non-existance
# check isHooked
li $v0, 118
syscall
beq $v0, $zero, mm_next # currently not isHooked
# move the mineral because it is hooked
li $v0, 110 # update location
syscall
mm_next: addi $s0, $s0, -1
j mm_loop
mm_exit: lw $ra, 8($sp)
lw $s0, 4($sp)
lw $s1, 0($sp)
addi $sp, $sp, 12
jr $ra

#——————————————————————–
# func: move_dynamites
# let the dynamites move forward
#——————————————————————–
move_dynamites: addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
la $t0, dynamite_num
lw $s0, 0($t0) # $s0: the number of dynamites
md_loop: beq $s0, $zero, md_exit
la $s1, dynamite_ids # $s1: unchanged till the end
addi $s0, $s0, -1 # dynamite_num-1 to be the index
sll $t0, $s0, 2
add $t1, $s1, $t0 # $t1: the address of id
lw $a0, 0($t1) # $a0: the id of a dynamite
beq $a0, $zero, md_loop # the dynamite does not exists
li $v0, 110 # update location
syscall
j md_loop
md_exit: lw $ra, 8($sp)
lw $s0, 4($sp)
lw $s1, 0($sp)
addi $sp, $sp, 12
jr $ra

#——————————————————————–
# func: destroy_minerals
# destroy all the minerals in Java memory
#——————————————————————–
destroy_minerals:
addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
la $t0, mineral_num
lw $s0, 0($t0) # $s0: the number of minerals
la $s1, mineral_ids # $s1: the id array
destroy_loop: beq $s0, $zero, destroy_exit
addi $t0, $s0, -1 # i = n – 1
sll $t0, $t0, 2
add $t1, $s1, $t0 # $t1: the address of id
lw $a0, 0($t1) # $a0: the id of a mineral
beq $a0, $zero, destroy_next # the mineral is destroyed already
li $v0, 107 # destroy mineral
syscall
sw $zero, 0($t1) # mineral_ids[i] = 0
destroy_next: addi $s0, $s0, -1
j destroy_loop
destroy_exit: lw $ra, 8($sp)
lw $s0, 4($sp)
lw $s1, 0($sp)
addi $sp, $sp, 12
jr $ra

#——————————————————————–
# func: destroy_dynamites
# destroy all the dynamites in Java memory
#——————————————————————–
destroy_dynamites:
addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $s1, 0($sp)
la $t0, dynamite_num
lw $s0, 0($t0) # $s0: the number of dynamites
la $s1, dynamite_ids # $s1: the id array
j destroy_loop # same as destroy minerals

#——————————————————————–
# func: get_time
# Get the current time
# $v0 = current time
#——————————————————————–
get_time: li $v0, 30
syscall # this syscall also changes the value of $a1
andi $v0, $a0, 0x3FFFFFFF # truncated to milliseconds from some years ago
jr $ra

#——————————————————————–
# func: have_a_nap(last_iteration_time, nap_time)
#——————————————————————–
have_a_nap: addi $sp, $sp, -8
sw $ra, 4($sp)
sw $s0, 0($sp)
add $s0, $a0, $a1
jal get_time
sub $a0, $s0, $v0
slt $t0, $zero, $a0
bne $t0, $zero, han_p
li $a0, 1 # sleep for at least 1ms
han_p: li $v0, 32 # syscall: let mars java thread sleep $a0 milliseconds
syscall
lw $ra, 4($sp)
lw $s0, 0($sp)
addi $sp, $sp, 8
jr $ra

#——————————————————————–
# func get_keyboard_input
# $v0: ASCII value of the input character if input is available;
# otherwise, the value is 0;
#——————————————————————–
get_keyboard_input:
addi $sp, $sp, -4
sw $ra, 0($sp)
add $v0, $zero, $zero
lui $a0, 0xFFFF
lw $a1, 0($a0)
andi $a1, $a1, 1
beq $a1, $zero, gki_exit
lw $v0, 4($a0)
gki_exit: lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra