summaryrefslogtreecommitdiff
path: root/GameEngine/PlayersCollection.py
diff options
context:
space:
mode:
Diffstat (limited to 'GameEngine/PlayersCollection.py')
-rw-r--r--GameEngine/PlayersCollection.py158
1 files changed, 158 insertions, 0 deletions
diff --git a/GameEngine/PlayersCollection.py b/GameEngine/PlayersCollection.py
new file mode 100644
index 0000000..10fa990
--- /dev/null
+++ b/GameEngine/PlayersCollection.py
@@ -0,0 +1,158 @@
+#+AUTHOR: bdunahu
+#+TITLE: PlayersCollection.py
+#+DESCRIPTION: methods for handling and querying snake objects
+
+import pygame as pg
+from random import randint
+from collections import namedtuple
+from enum import Enum
+
+class Direction(Enum):
+ UP = 0
+ RIGHT = 1
+ DOWN = 2
+ LEFT = 3
+
+Point = namedtuple('Point', 'x, y')
+
+YELLOW = (255,255,0)
+RED = (255,0,0)
+PURPLE = (204,51,255)
+WHITE = (255,255,255)
+PLAYER_COLOR = [YELLOW, RED, PURPLE, WHITE]
+
+WINDOW_WIDTH = 640
+WINDOW_HEIGHT = 480
+GAME_UNITS = 40
+DISPLAY = None
+
+class Players():
+ def __init__(self, snake_size, num_players, display, window_width=640, window_height=480, game_units=40):
+ ''' define array list of new Snake objects '''
+ global WINDOW_WIDTH
+ global WINDOW_HEIGHT
+ global GAME_UNITS
+ global DISPLAY
+
+ WINDOW_WIDTH = window_width
+ WINDOW_HEIGHT = window_height
+ GAME_UNITS = game_units
+ DISPLAY = display
+
+ self._index = 0
+ self.num_players = num_players
+
+ self.players = [Snake(snake_size, player_id)
+ for player_id in range(num_players)]
+
+ def __iter__(self):
+ return iter(self.players)
+
+ def __getitem__(self, index):
+ return self.players[index]
+
+ def full_reset(self):
+ ''' reset every snake position '''
+ # map(lambda player:player.reset(), self.players)
+ for player in self.players:
+ player.reset()
+
+ def move_all(self):
+ ''' move all snakes '''
+ # map(lambda player:player.move(), self.players)
+ for player in self.players:
+ player.move()
+
+ def reward_killer(self, player):
+ ''' split play length up against killing snakes '''
+ killer = self._point_lookup(player.head)
+ if not killer == None and not killer == player:
+ rewards = player.score.curr_score + player.size
+ killer.deficit += rewards
+ killer.score.curr_score += rewards
+ killer.score.total_score += rewards
+
+ def _point_lookup(self, head):
+ for player in self.players:
+ if head in player.snake:
+ return player
+ return None
+
+ def draw(self):
+ ''' draw all snakes '''
+ # map(lambda player:player.draw(), self.players)
+ for player in self.players:
+ player.draw()
+
+class Snake():
+ def __init__(self, initial_size, player_id):
+ ''' define initial size (length), direction, and position '''
+ self.player_id = player_id
+ self.size = initial_size
+ self.direction = None
+ self.head = None
+ self.snake = []
+ self.score = Score(self.player_id)
+ self.deficit = 0 # for how many moves does this snake need to grow?
+
+ def reset(self):
+ self.score.reset()
+ self.deficit = 0
+ self.direction = Direction.RIGHT.value
+ x = randint(0, (WINDOW_WIDTH-GAME_UNITS )//GAME_UNITS )*GAME_UNITS
+ y = randint(0, (WINDOW_HEIGHT-GAME_UNITS )//GAME_UNITS )*GAME_UNITS
+ self.head = Point(x,y)
+ self.snake = [self.head]
+ for seg in range(self.size-1):
+ self.snake.append(Point(self.head.x-(seg*GAME_UNITS), self.head.y))
+
+ def move(self):
+ ''' update snake coordinates by inserting new head '''
+ x = self.head.x
+ y = self.head.y
+ if self.direction == Direction.RIGHT.value:
+ x += GAME_UNITS
+ if self.direction == Direction.LEFT.value:
+ x -= GAME_UNITS
+ if self.direction == Direction.DOWN.value:
+ y += GAME_UNITS
+ if self.direction == Direction.UP.value:
+ y -= GAME_UNITS
+
+ self.head = Point(x, y)
+ self.snake.insert(0,self.head)
+
+ def in_wall(self):
+ return True if (self.head.x > WINDOW_WIDTH - GAME_UNITS or
+ self.head.x < 0 or
+ self.head.y > WINDOW_HEIGHT - GAME_UNITS or
+ self.head.y < 0) else False
+
+ def draw(self):
+ ''' draw rectangle(s) directly on field '''
+ for seg in self.snake: # see explanation in engine.org
+ pg.draw.rect(DISPLAY, PLAYER_COLOR[self.player_id], pg.Rect(seg.x, seg.y,
+ GAME_UNITS, GAME_UNITS))
+ self.score.draw()
+
+class Score():
+ def __init__(self, player_id):
+ ''' initialize score counter '''
+ self.player_id = player_id
+ self.font = pg.font.SysFont("monospace", 16)
+ self.curr_score = 0
+ self.total_score = 0
+ self.deaths = 0
+ self.kills = 0
+
+ def scored(self):
+ self.curr_score += 1
+ self.total_score += 1
+
+ def reset(self):
+ self.curr_score = 0
+
+ def draw(self):
+ ''' draw score on top left '''
+ score_surf = self.font.render(f'Current: {self.curr_score} Total: {self.total_score}', True, PLAYER_COLOR[self.player_id])
+ DISPLAY.blit(score_surf, (0, 0+24*self.player_id))