Cleaning and docs
This commit is contained in:
parent
aae3128737
commit
f692e6c8f2
25
headless.py
25
headless.py
|
@ -2,19 +2,40 @@
|
|||
|
||||
from tron.map import Map
|
||||
from tron.game import Game, PositionPlayer
|
||||
from tron.player import Player, Direction, ConstantPlayer, KeyboardPlayer
|
||||
from tron.player import Direction, ConstantPlayer
|
||||
|
||||
# This script shows how to create a game with AI, that will run automatically.
|
||||
# It is made to be fast and not to be used by humans. It especially doesn't
|
||||
# display and window and doesn't listen to any keystrokes.
|
||||
|
||||
def main():
|
||||
# Prepare the size for the game.
|
||||
# Those values may be good if you want to play, they might not be so good
|
||||
# to train your AI. Decreasing them will make the learning faster.
|
||||
width = 40
|
||||
height = 40
|
||||
|
||||
# Create a game from its size and its players
|
||||
game = Game(width, height, [
|
||||
PositionPlayer(1, KeyboardPlayer(Direction.RIGHT), [0, 0]),
|
||||
# Here we create two players with constant direction.
|
||||
# It's not very interesting but it's the basis of everything else.
|
||||
PositionPlayer(1, ConstantPlayer(Direction.RIGHT), [0, 0]),
|
||||
PositionPlayer(2, ConstantPlayer(Direction.LEFT), [width - 1, height - 1]),
|
||||
])
|
||||
|
||||
# Run the game.
|
||||
# Since no window is passed as parameter, not only the game will not
|
||||
# display anything, which avoid doing useless computations, but it will
|
||||
# also not be limited to a certain framerate, which would be necessary for
|
||||
# human users.
|
||||
game.main_loop()
|
||||
|
||||
# The game is done, you can get information about it and do what you want.
|
||||
if game.winner is None:
|
||||
print("It's a draw!")
|
||||
else:
|
||||
print('Player {} wins!'.format(game.winner))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
27
play.py
27
play.py
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Import pygame without printing anything on the terminal
|
||||
import contextlib
|
||||
with contextlib.redirect_stdout(None):
|
||||
import pygame
|
||||
|
@ -7,23 +8,43 @@ with contextlib.redirect_stdout(None):
|
|||
from tron.map import Map
|
||||
from tron.game import Game, PositionPlayer
|
||||
from tron.window import Window
|
||||
from tron.player import Player, Direction, ConstantPlayer, KeyboardPlayer
|
||||
from tron.player import Direction, KeyboardPlayer, Mode
|
||||
|
||||
# This script shows how to create a game with human players and play it interactively.
|
||||
# It shows how to create the game, to setup interactive controls for users, and
|
||||
# to run the game while rendering it on a window with a reasonnable framerate.
|
||||
|
||||
def main():
|
||||
# Initialize the game engine
|
||||
pygame.init()
|
||||
|
||||
# Prepare the size for the game.
|
||||
# Those values may be good if you want to play, they might not be so good
|
||||
# to train your AI. Decreasing them will make the learning faster.
|
||||
width = 40
|
||||
height = 40
|
||||
|
||||
# Create a game from its size and its players
|
||||
game = Game(width, height, [
|
||||
PositionPlayer(1, KeyboardPlayer(Direction.RIGHT), [0, 0]),
|
||||
PositionPlayer(2, ConstantPlayer(Direction.LEFT), [width - 1, height - 1]),
|
||||
# We create two PositionPlayer for each player of the game.
|
||||
# The first one has the id 1, and will use keyboard interaction, with a
|
||||
# default direction that will be to the right, and that will use the Z,
|
||||
# Q, S and D keys.
|
||||
# The last array defines the initial position of the player.
|
||||
PositionPlayer(1, KeyboardPlayer(Direction.RIGHT, Mode.ZQSD), [0, 0]),
|
||||
|
||||
# We create a second player that will use the arrow keys.
|
||||
PositionPlayer(2, KeyboardPlayer(Direction.LEFT, Mode.ARROWS), [width - 1, height - 1]),
|
||||
])
|
||||
|
||||
# Create a window for the game so the players can see what they're doing.
|
||||
window = Window(game, 10)
|
||||
|
||||
# Run the game.
|
||||
game.main_loop(window)
|
||||
|
||||
# Once the game is finished, if game.winner is None, it means it's a draw
|
||||
# Otherwise, game.winner will tell us which player has won the game.
|
||||
if game.winner is None:
|
||||
print("It's a draw!")
|
||||
else:
|
||||
|
|
26
tron/game.py
26
tron/game.py
|
@ -11,7 +11,7 @@ class Winner(Enum):
|
|||
PLAYER_ONE = 1
|
||||
PLAYER_TWO = 2
|
||||
|
||||
class Case(Enum):
|
||||
class Tile(Enum):
|
||||
"""
|
||||
The different type of elements that can be in a map.
|
||||
"""
|
||||
|
@ -26,17 +26,17 @@ class Case(Enum):
|
|||
"""
|
||||
Converts an element of a map to a nice color.
|
||||
"""
|
||||
if self == Case.EMPTY:
|
||||
if self == Tile.EMPTY:
|
||||
return (255, 255, 255)
|
||||
elif self == Case.WALL:
|
||||
elif self == Tile.WALL:
|
||||
return (0, 0, 0)
|
||||
elif self == Case.PLAYER_ONE_BODY:
|
||||
elif self == Tile.PLAYER_ONE_BODY:
|
||||
return (128, 0, 0)
|
||||
elif self == Case.PLAYER_ONE_HEAD:
|
||||
elif self == Tile.PLAYER_ONE_HEAD:
|
||||
return (255, 0, 0)
|
||||
elif self == Case.PLAYER_TWO_BODY:
|
||||
elif self == Tile.PLAYER_TWO_BODY:
|
||||
return (0, 128, 0)
|
||||
elif self == Case.PLAYER_TWO_HEAD:
|
||||
elif self == Tile.PLAYER_TWO_HEAD:
|
||||
return (0, 255, 0)
|
||||
else:
|
||||
return None
|
||||
|
@ -57,18 +57,18 @@ class PositionPlayer:
|
|||
Returns the body type of the PP depending on its id.
|
||||
"""
|
||||
if self.id == 1:
|
||||
return Case.PLAYER_ONE_BODY
|
||||
return Tile.PLAYER_ONE_BODY
|
||||
elif self.id == 2:
|
||||
return Case.PLAYER_TWO_BODY
|
||||
return Tile.PLAYER_TWO_BODY
|
||||
|
||||
def head(self):
|
||||
"""
|
||||
Returns the head type of the PP depending of its id.
|
||||
"""
|
||||
if self.id == 1:
|
||||
return Case.PLAYER_ONE_HEAD
|
||||
return Tile.PLAYER_ONE_HEAD
|
||||
elif self.id == 2:
|
||||
return Case.PLAYER_TWO_HEAD
|
||||
return Tile.PLAYER_TWO_HEAD
|
||||
|
||||
class HistoryElement:
|
||||
"""
|
||||
|
@ -98,7 +98,7 @@ class Game:
|
|||
"""
|
||||
self.width = width
|
||||
self.height = height
|
||||
mmap = Map(width, height, Case.EMPTY, Case.WALL)
|
||||
mmap = Map(width, height, Tile.EMPTY, Tile.WALL)
|
||||
self.history = [HistoryElement(mmap, None, None)]
|
||||
self.pps = pps
|
||||
self.winner = None
|
||||
|
@ -153,7 +153,7 @@ class Game:
|
|||
pp.alive = False
|
||||
|
||||
# Check collision
|
||||
elif self.map()[pp.position[0], pp.position[1]] is not Case.EMPTY:
|
||||
elif self.map()[pp.position[0], pp.position[1]] is not Tile.EMPTY:
|
||||
pp.alive = False
|
||||
|
||||
else:
|
||||
|
|
|
@ -52,18 +52,56 @@ class Player:
|
|||
"""
|
||||
pass
|
||||
|
||||
class Mode(Enum):
|
||||
"""
|
||||
The different type of interaction for the keyboard controls.
|
||||
|
||||
This will allow to play with two humans.
|
||||
"""
|
||||
ARROWS = 1
|
||||
ZQSD = 2
|
||||
|
||||
class KeyboardPlayer(Player):
|
||||
""""
|
||||
This is the key board interaction.
|
||||
|
||||
It uses Z, Q, S and D keys to move the tron.
|
||||
It uses keys depending on the mode.
|
||||
"""
|
||||
def __init__(self, initial_direction):
|
||||
def __init__(self, initial_direction, mode = Mode.ARROWS):
|
||||
"""
|
||||
Creates a keyboard decision with a default direction.
|
||||
"""
|
||||
super(KeyboardPlayer, self).__init__()
|
||||
self.direction = initial_direction
|
||||
self.mode = mode
|
||||
|
||||
def left(self):
|
||||
"""
|
||||
Returns the left key of the player depending on the mode.
|
||||
"""
|
||||
import pygame
|
||||
return pygame.K_q if self.mode == Mode.ZQSD else pygame.K_LEFT
|
||||
|
||||
def right(self):
|
||||
"""
|
||||
Returns the right key of the player depending on the mode.
|
||||
"""
|
||||
import pygame
|
||||
return pygame.K_d if self.mode == Mode.ZQSD else pygame.K_RIGHT
|
||||
|
||||
def down(self):
|
||||
"""
|
||||
Returns the down key of the player depending on the mode.
|
||||
"""
|
||||
import pygame
|
||||
return pygame.K_s if self.mode == Mode.ZQSD else pygame.K_DOWN
|
||||
|
||||
def up(self):
|
||||
"""
|
||||
Returns the up key of the player depending on the mode.
|
||||
"""
|
||||
import pygame
|
||||
return pygame.K_z if self.mode == Mode.ZQSD else pygame.K_UP
|
||||
|
||||
def manage_event(self, event):
|
||||
"""
|
||||
|
@ -71,13 +109,13 @@ class KeyboardPlayer(Player):
|
|||
"""
|
||||
import pygame
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_q:
|
||||
if event.key == self.left():
|
||||
self.direction = Direction.LEFT
|
||||
if event.key == pygame.K_z:
|
||||
if event.key == self.up():
|
||||
self.direction = Direction.UP
|
||||
if event.key == pygame.K_d:
|
||||
if event.key == self.right():
|
||||
self.direction = Direction.RIGHT
|
||||
if event.key == pygame.K_s:
|
||||
if event.key == self.down():
|
||||
self.direction = Direction.DOWN
|
||||
|
||||
def action(self, game):
|
||||
|
|
Loading…
Reference in New Issue