Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A proposal for two-teams game #37

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
An easy AI fork that adds teams of players support
165 changes: 165 additions & 0 deletions easyAI/TwoTeamsGame.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
from copy import deepcopy


class TwoTeamsGame:

def __init__(self, team1, team2, player_selector):
"""
:param team1: array of easyAI-supported objects. See Player module
:param team2: array of easyAI-supported objects.
:param player_selector constructor for objects of type AbstractOrderedPlayerSelector (see below)
"""
self.player_selector = player_selector(team1, team2)
self.setup_game()

def setup_game(self):
"""
put here your own initialization and so on
:return:
"""
raise NotImplementedError('Abstract method')

def make_move(self, move):
raise NotImplementedError('Abstract method')

def show(self):
raise NotImplementedError('Abstract method')

def is_over(self):
raise NotImplementedError('Abstract method')


def play(self, nmoves=1000, verbose=True):

history = []

if verbose:
self.show()

for self.nmove in range(1, nmoves + 1):

if self.is_over():
break

move = self.player.ask_move(self)
history.append((deepcopy(self), move))
self.make_move(move)

if verbose:
self.show()

self.switch_player()

history.append(deepcopy(self))

return history


@property
def opponent_team(self):
return self.current_opponent_team()

@property
def player(self):
return self.current_player()

@property
def nplayer(self):
return self.current_player().name

def current_player(self):
return self.player_selector.current_player()

def current_opponent_team(self):
return self.player_selector.opponent_team()

def current_team(self):
return self.player_selector.current_team()

def switch_player(self):
self.player_selector.next_player()

def copy(self):
return deepcopy(self)

def get_move(self):
"""
Method for getting a move from the current player. If the player is an
AI_Player, then this method will invoke the AI algorithm to choose the
move. If the player is a Human_Player, then the interaction with the
human is via the text terminal.
"""
return self.player.ask_move(self)

def play_move(self, move):
"""
Method for playing one move with the current player. After making the move,
the current player will change to the next player.

Parameters
-----------

move:
The move to be played. ``move`` should match an entry in the ``.possibles_moves()`` list.
"""
result = self.make_move(move)
self.switch_player()
return result

class AbstractOrderedPlayerSelector:
"""
Base class for player selectors. Selects next player in order, the behaviour is:

team1 - player1
team2 - player 1

team 1 - player 2
team 2 - player 2

etc

according to rules defined in filter_team
"""

def __init__(self, team1, team2):
self.teams = [team1, team2]
self.move_no = 0
self.counters = [0, 0]

def filter_team(self, team):
"""
Filters an array of players. Used for return active players. For example in a RPG game may be the still alive ones
:param team:
:return:
"""
raise NotImplementedError('Abstract method')

def current_player(self):

team_id = self._current_team_id()
team = self.current_team()

character_id = self.counters[team_id] % len(team)

return team[character_id]

def _current_team_id(self):
return self.move_no % 2

def _next_team_id(self):
return (self.move_no + 1) % 2

def next_player(self):
"""
Moves pointer to next player
:return:
"""
team_id = self._current_team_id()
self.counters[team_id] += 1
self.move_no += 1

def current_team(self):
return self.filter_team(self.teams[self._current_team_id()])

def opponent_team(self):
return self.filter_team(self.teams[self._next_team_id()])
32 changes: 32 additions & 0 deletions easyAI/two_teams_game_sandbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from easyAI.TwoTeamsGame import TwoTeamsGame, AbstractOrderedPlayerSelector

from easyAI import Human_Player

class MyGame(TwoTeamsGame):
"""
a dummy class for making experiments. With this script it ends up at 4 moves, and nothing happens :-)
"""

def make_move(self, move):
print(str(self.player.name) + ' makes ' + move)

def is_over(self):
return False

def show(self):
print('Possible moves: ' + str(self.possible_moves()))

def setup_game(self):
pass

def possible_moves(self):
return ['1']

class MyPlayerSelector(AbstractOrderedPlayerSelector):
def filter_team(self, team):
return team



g = MyGame([Human_Player()], [Human_Player()], MyPlayerSelector)
g.play(nmoves=4)