project_game/gamefiles/board.py

118 lines
4.6 KiB
Python

from man import Man
from snack import Snack
from mine import Mine
from random import shuffle
'''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],
[20, 40],
[30,50],
[40,60],
[50,70],
[60,80],
[70,90]
]
class Board:
display = False
snack=False
mine=False
def __init__(self,width, height,num_snacks,state):
self.width = width
self.height = height
self.num_snacks = num_snacks
self.state = state
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])]
snacks = [Snack(p) for p in all_positions[1:(num_snacks+1)]]
mines = [Mine(p) for p in all_positions[(num_snacks + 2):(num_snacks + num_mines +2)]]
agents = man + snacks + mines + [self]
return agents
def play_turn(self,game):
'''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
while not game.is_empty(all_positions[index]):
index = index + 1
mine = Mine(all_positions[index])
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):
'''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
while not game.is_empty(all_positions[index]):
index = index + 1
snack = Snack(all_positions[index])
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_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):
positions.append((i,j))
return positions