almost done, just one issue with display score

This commit is contained in:
Chris Mekelburg 2024-12-11 22:34:22 -05:00
parent 5980c6bb22
commit 60a4069e87
11 changed files with 70 additions and 137 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -2,14 +2,23 @@ from man import Man
from snack import Snack
from mine import Mine
from random import shuffle
from minecounter import mine_counter
MAX_MINES = 50
'''This class sets up the board initially, but also is responsible for adding snacks
and mines after they are consumed. Also increases mines as game gets more difficult.'''
'''Values to call later, sets no more than 100 mines, and each list represent a level [score, num_mines],
which is called in mine_counter below.'''
MAX_MINES = 100
LEVELS = [
[5, 10],
[10, 20],
[15, 30],
[100, 40]
[20, 40],
[30,50],
[40,60],
[50,70],
[60,80],
[70,90]
]
class Board:
@ -17,24 +26,19 @@ class Board:
snack=False
mine=False
def __init__(self,width, height,num_snacks):
def __init__(self,width, height,num_snacks,state):
self.width = width
self.height = height
self.num_snacks = num_snacks
#self.num_mines = num_mines
def mine_counter(self,game):
current_score_dict = game.state
current_score = current_score_dict['Score']
for limit, n in LEVELS:
if current_score < limit:
return n
return MAX_MINES
self.state = state
def get_agents(self,num_snacks):
num_mines = int(self.mine_counter)
print(num_mines)
def get_agents(self,num_snacks,state):
'''Sets up all the agents (snacks, mines, and man) in the game. First, determines mines needed by
calling the mine_counter function. Then generates a list of all posiitons, randomizes them, and assigns
the man to the first random position, the snacks to the next num_snack positions, and then the mines
to the required number of posiitons as specified in mine_counter. Returns these agents so they can be
positioned on the board.'''
num_mines = self.mine_counter(state)
all_positions = self.get_all_positions()
shuffle(all_positions)
man= [Man(all_positions[0])]
@ -44,13 +48,28 @@ class Board:
return agents
def play_turn(self,game):
game.log(self.num_mines)
'''Checks after every turn (turn is length of time specified in retro) if the game needs snacks
or mines.'''
game.log(game.state['Score'])
while self.game_needs_snacks(game):
self.add_snack(game)
while self.game_needs_mines(game):
self.add_mine(game)
def mine_counter(self,state):
'''Determines how many mines should be in the game, based on the score of the game. Refers to the
LEVELS list above which contains the score and a correspponding number of mines. This function
puts a certain number of mines down based on the score. Currently, does not reduce the number
of mines when the score lowers after hitting a mine. Returns the number of mines needed. '''
score = state['Score']
for limit, n in LEVELS:
if score < limit:
return n
return MAX_MINES
def add_mine(self,game):
'''Adds a mine by finding all positions, randomizing them, and then adding a mine to the
first non-occupied position.'''
all_positions=self.get_all_positions()
shuffle(all_positions)
index =0
@ -60,14 +79,18 @@ class Board:
game.add_agent(mine)
def count_mines(self,game):
'''Counts the number of mines currently in the game.'''
mines= [a for a in game.agents if a.mine]
return len(mines)
def game_needs_mines(self,game):
return self.count_mines(game) < self.num_mines
'''Returns true when the number of mines in the game is less than the number of mines
required based on the score.'''
return self.count_mines(game) < self.mine_counter(game.state)
def add_snack(self,game):
'''Adds a snack by finding all positions, randomizing them, and then adding a snack to the
first non-occupied position.'''
all_positions=self.get_all_positions()
shuffle(all_positions)
index =0
@ -77,52 +100,17 @@ class Board:
game.add_agent(snack)
def count_snacks(self,game):
'''Counts the number of snacks currently in the game.'''
snacks= [a for a in game.agents if a.snack]
return len(snacks)
def game_needs_snacks(self,game):
'''Returns true when the number of snacks in the game is less than the number of snacks specified
in nav-game.py. In a future version, this number of snacks could vary as the game gets more difficult.'''
return self.count_snacks(game) < self.num_snacks
'''
def get_agents(self,num_snacks,num_mines):
man = self.get_man(num_snacks,num_mines)
snacks = self.get_snacks(num_snacks)
mines = self.get_mines(num_mines,num_snacks)
agents = snacks + mines + man
return agents
def get_man(self,num_snacks,num_mines):
#man_location = [Man(all_positions[0])]
#return man_location
shuffle(all_positions)
for position in all_positions:
#if position in self.get_snacks(num_snacks):
# all_positions.remove(position)
if position in self.get_mines(num_mines,num_snacks):
all_positions.remove(position)
man_location = [Man(all_positions[0])]
return man_location
def get_mines(self,num_mines, num_snacks):
all_positions = self.get_all_positions()
shuffle(all_positions)
for position in all_positions:
if position in self.get_snacks(num_snacks):
all_positions.remove(position)
mines = [Mine(p) for p in all_positions[1:num_mines+1]]
return mines
def get_snacks(self,num_snacks):
all_positions = self.get_all_positions()
shuffle(all_positions)
snacks = [Snack(p) for p in all_positions[1:num_snacks+1]]
return snacks
'''
def get_all_positions(self):
'''Finds all coordinate positions in the game and adds them to a list of positions.'''
positions=[]
for i in range(self.width):
for j in range(self.height):

View File

@ -1,12 +1,12 @@
from retro.agent import ArrowKeyAgent
#from retro.game import Game
#from helpers import add, get_occupant
from retro.game import Game
from random import shuffle
from snack import Snack
width=25
height=25
'''Establishes keyboard arrow keys as direction vectors so each arrow key corresponds with movement
in a certain direction on the board.'''
direction_vectors = {
"KEY_RIGHT": (1, 0),
"KEY_UP": (0, -1),
@ -15,7 +15,7 @@ direction_vectors = {
}
class Man:
character = "&" #try google asci full table?,
character = "&"
color = "blue"
snack=False
mine=False
@ -23,18 +23,17 @@ class Man:
def __init__(self,position):
self.position = position
'''Describes how a keystroke is received'''
def handle_keystroke(self, keystroke, game):
'''Describes how a keystroke is received'''
if keystroke.name in direction_vectors:
vector = direction_vectors[keystroke.name]
self.try_to_move(vector, game)
'''Checks if a space is avialable to move. Also adds 1 point if the space
contains a snack and then removes the snack. Deducts 10 points if the
space contains a mine. Checks that the score is not negative and if it
is, ends the game.'''
def try_to_move(self, vector, game):
'''Checks if a space is avialable to move. Also adds 1 point if the space
contains a snack and then removes the snack. Deducts 10 points if the
space contains a mine. Checks that the score is not negative and if it
is, ends the game. Also stores the score so it can be used to determine if more mines are needed'''
x,y = self.position
vx,vy = vector
future_position = (x +vx, y+vy)
@ -45,7 +44,6 @@ class Man:
obstacle = agents[0]
else:
obstacle= None
if on_board:
if obstacle:
if obstacle.snack:
@ -61,38 +59,8 @@ class Man:
else:
self.position = future_position
def die(self,game):
'''Indicates what happens when the game is over.'''
game.state["message"] = "Game Over"
game.state["Message"] = "Game Over"
self.color = "black"
game.end()
'''
def __init__(self, position):
self.position = position
def handle_keystroke(self, keystroke, game):
if keystroke.name in direction_vectors:
vector = direction_vectors[keystroke.name]
self.try_to_move(vector, game)
def try_to_move(self, vector, game):
"""Tries to move the player in the direction of vector.
If the space is empty and it's on the board, then the move succeeds.
If the space is occupied, then if the occupant can be pushed, it gets
pushed and the move succeeds. Otherwise, the move fails.
"""
future_position = add(self.position, vector)
on_board = game.on_board(future_position)
obstacle = get_occupant(game, future_position)
if obstacle:
if obstacle.deadly:
self.die(game)
elif obstacle.handle_push(vector, game):
self.position = future_position
elif on_board:
self.position = future_position'''

View File

@ -1,3 +1,6 @@
'''Sets up the mine object.'''
class Mine:
character = "*"
color = "green"

View File

@ -1,30 +1,2 @@
MAX_MINES = 50
LEVELS = [
[5, 10],
[10, 20],
[15, 30],
[100, 40]
]
def mine_counter(state):
current_score = state['Score']
for limit, n in LEVELS:
if current_score < limit:
return n
return MAX_MINES
'''
if score < 5:
num_mines = 10
if 10 <= score <50:
num_mines = 20
if 50 <= score <75:
num_mines = 30
if 75 <= score <100:
num_mines = 40
#else:
#num_mines = 50
return num_mines
'''
'''Not currently in use, may use if minecounter needs to be more complex
but for now it is included in board.py'''

View File

@ -1,18 +1,18 @@
from retro.game import Game
from board import Board
'''This contains the main info for setting up and running the game.'''
width = 25
height = 25
state= {"Score":0}
score = state["Score"]
state= {"Score":00}
num_snacks = 10
board = Board(width,height,num_snacks)
board = Board(width,height,num_snacks,state) #sets the original board
game = Game(
board.get_agents(num_snacks),
board.get_agents(num_snacks,state),
state,
board_size = (width, height),debug=True
)
game.play()
#print(board.num_mines)
game.play()

View File

@ -1,3 +1,5 @@
'''Sets up the snack object'''
class Snack:
character = "o"
color = "red"