This is my first attempt to make a game on my own. I just want to see if anyone has any comments. Am I doing things, at least, sort of alright? Is there a better way I could deal with the input?
import sys, platform, os
import time, random, math
class Entity(object):
'''Basic entity object
Has position and character'''
def __init__(self, name, x, y, hp, char, state):
self.name = name
self.x = x
self.y = y
self.hp = hp
self.char = char
self.state = state
def move(self, direction, board):
'''To update entity position'''
if direction == 'left' and board.is_valid_move(self, (self.x, self.y - 1)):
self.y -= 1
elif direction == 'right' and board.is_valid_move(self, (self.x, self.y + 1)):
self.y += 1
elif direction == 'up' and board.is_valid_move(self, (self.x - 1, self.y)):
self.x -= 1
elif direction == 'down' and board.is_valid_move(self, (self.x + 1, self.y)):
self.x += 1
def attack(self, target):
target.hp -= 1
def distance(self, target, pos=()):
'''Get distance from self to target'''
if not pos:
x, y = self.x, self.y
else:
x, y, = pos
return math.sqrt((x - target.x)**2 + (y - target.y)**2)
def move_toward(self, target, board, pos=()):
'''Moves entity towards target'''
move_dict = {
'right' : self.distance(target, (self.x, self.y + 1)),
'left' : self.distance(target, (self.x, self.y - 1)),
'up' : self.distance(target, (self.x - 1, self.y)),
'down' : self.distance(target, (self.x + 1, self.y))
}
small_index = move_dict.values().index(min(move_dict.values()))
small_key = move_dict.keys()[small_index]
self.move(small_key, board)
def change_state(self, state):
'''Change Entity state. Only for death right now.'''
self.state = state
def update(self, board):
'''Update Entity, check hp, xp, ect.'''
if self.hp <= 0 and self.state == 'dead':
time.sleep(1)
pass
elif self.hp <= 0 and self.state != 'dead':
self.change_state('dead')
self.char = '%'
class Board(object):
'''Board class to create empty grid of cells'''
def __init__(self, x_size, y_size, char='-'):
self.x_size = x_size
self.y_size = y_size
self.char = char
self.board = [[char for _ in range(x_size)] for _ in range(y_size)]
def print_board(self, board, ents):
'''To draw the board'''
self.clear_screen()
for ent in ents:
self.print_char(ent, ent.char)
for _ in self.board:
print ' '.join(_)
def print_char(self, ent, char='-'):
'''Print a character to the board
By default, prints empty cell'''
self.board[ent.x][ent.y] = char
def clear_screen(self):
if platform.system() == 'Linux':
os.system('clear')
elif platform.system() == 'Windows':
os.system('cls')
else:
print 'Clear screen is not working.'
def is_vacant(self, x, y):
if self.board[x][y] == '-':
return True
else:
return False
def is_valid_move(self, ent, future_pos):
moves = []
adj_cells = [(ent.x+1, ent.y),(ent.x-1, ent.y),
(ent.x, ent.y+1),(ent.x, ent.y-1)]
for (x,y) in adj_cells:
if not x >= self.x_size and not y >= self.y_size \
and not x <= self.x_size - self.x_size - 1 \
and not y <= self.y_size - self.y_size - 1 \
and self.is_vacant(x, y):
moves.append((x,y))
if future_pos in moves:
return True
else:
return False
##
# Functions
##
def type_text(string, sec):
for _ in string:
if sec == 'random':
sec = random.uniform(0.1, 0.2) if sec == 'random' else sec
sys.stderr.write(_)
time.sleep(sec)
def enemy_turn(enemy, player, board):
distance = enemy.distance(player, (enemy.x, enemy.y))
if distance == 1 and player.state != 'dead':
enemy.attack(player)
elif distance < 4 and player.state != 'dead':
board.print_char(enemy)
enemy.move_toward(player, board, (enemy.x, enemy.y))
else:
moves = ['up', 'down', 'left', 'right']
move = random.choice(moves) # Sweet. Oh yes, very sweet <3
board.print_char(enemy)
enemy.move(move, board)
def player_turn(player, board):
player.update(board.board)
if player.state == 'dead':
print 'You are dead.'
return
m_actions = {
'move' : ['move', 'walk', 'run', 'sprint'],
'die' : ['die']
}
s_actions = {
'move' : ['up', 'down', 'left', 'right']
}
choice = raw_input('What do you want to do? :> ')
parts = [x.strip() for x in choice.split(',')]
if len(parts) < 2:
if parts[0] in m_actions['move']:
direction = raw_input('Which direction? :> ')
parts.append(direction.strip())
if parts[1] in s_actions['move']:
board.print_char(player)
player.move(parts[1], board)
elif parts[0] in m_actions['die']:
player.hp = 0
board.print_char(player)
elif len(parts) == 2:
if parts[1] in s_actions['move']:
board.print_char(player)
player.move(parts[1], board)
def main():
## Title ##
sys.stdout.write("\x1b]2;Grid_Battle V0.1\x07")
# Initiate #
board = Board(5, 5)
player = Entity('Aet', 0, 0, 5, 'o', 'alive')
enemy = Entity('Monster', 4, 4, 5, 'x', 'alive')
objects = [player, enemy]
board.clear_screen()
type_text('Welcome', 'random')
type_text('.', 3)
board.print_board(board, objects)
while True:
if player.state == 'dead':
print player.name, 'is dead.'
print 'HP:', player.hp
player_turn(player, board)
board.print_board(board, objects)
enemy_turn(enemy, player, board)
board.print_board(board, objects)
if __name__ == '__main__':
main()