-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from DanielBarton446/random_agent
random agent
- Loading branch information
Showing
6 changed files
with
186 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
black | ||
pylint | ||
flameprof | ||
mypy | ||
isort |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
""" | ||
Agent class is the base class for all agents. | ||
""" | ||
|
||
from environment import Environment | ||
from shogi import Board | ||
|
||
|
||
class Agent: | ||
""" | ||
Agent is not a class itself, it is a base class for all agents. | ||
Agent should not be used for anything other than inheritance. | ||
""" | ||
|
||
def __init__(self, env: Environment, strategy=None): | ||
self._env = env | ||
self.strategy = strategy | ||
|
||
def select_action(self): | ||
""" | ||
Select an action based on the state of the environment. | ||
NotImplementedError: This method must be implemented by the subclass | ||
""" | ||
raise NotImplementedError("select_action method must be implemented") | ||
|
||
def action_space(self): | ||
""" | ||
Get the action space of the environment. | ||
Returns: | ||
action_space: The action space of the environment. | ||
""" | ||
return self._env.action_space | ||
|
||
@classmethod | ||
def from_board(cls, board: Board): | ||
""" | ||
Generate an agent from a shogi board. | ||
""" | ||
raise NotImplementedError("from_board method must be implemented") | ||
|
||
@property | ||
def env(self): | ||
""" | ||
env: The environment the agent operates in. | ||
""" | ||
return self._env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
""" | ||
You can use the Environment class to generate an environment from a shogi board | ||
``` | ||
from shogi import Board | ||
from environment import Environment | ||
board = Board() | ||
env = Environment(board) | ||
``` | ||
""" | ||
|
||
from typing import List | ||
|
||
from shogi import Board | ||
|
||
|
||
class Environment: | ||
""" | ||
Environment class for a shogi board. | ||
""" | ||
def __init__(self, board: Board): | ||
self.board = board | ||
self._moves: List = [] | ||
self._last_state = board.piece_bb | ||
|
||
@property | ||
def action_space(self): | ||
""" | ||
generate all legal moves if we haven't already and | ||
return them | ||
""" | ||
if self._moves and (self.board == self._last_state): | ||
return self._moves | ||
|
||
self._moves = [] | ||
self._last_state = self.board.piece_bb | ||
for move in self.board.legal_moves: | ||
self._moves.append(move) | ||
return self._moves | ||
|
||
def from_board(self, board: Board): | ||
""" | ||
currently just is another constructor basically. | ||
""" | ||
return Environment(board) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
""" | ||
This is the main function for an example of how you can have two | ||
agents play against each other. The agents are random agents, so | ||
the game will be random. | ||
This example with random moves also serves as a good example of | ||
how viable monte carlo tree search would be for this game. | ||
""" | ||
|
||
import shogi | ||
from environment import Environment | ||
from random_agent import RandomAgent | ||
from shogi import Board, Move | ||
|
||
|
||
def main() -> None: | ||
""" | ||
Main function for the example. | ||
""" | ||
board: Board = shogi.Board() | ||
|
||
agent1: RandomAgent = RandomAgent.from_board(board) | ||
env: Environment = agent1.env | ||
agent2: RandomAgent = RandomAgent(env) | ||
|
||
while not board.is_game_over(): | ||
agent1_action: Move = agent1.select_action() | ||
board.push(agent1_action) | ||
if board.is_game_over(): | ||
break | ||
|
||
agent2_action: Move = agent2.select_action() | ||
board.push(agent2_action) | ||
|
||
print("Final State of board:") | ||
print(board) | ||
print(f"Number of moves {len(board.move_stack)}") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
""" | ||
Random Agent: | ||
- This agent selects a random move from the action space. | ||
- This agent will be used for monte carlo tree search. | ||
""" | ||
|
||
import random | ||
|
||
from agent import Agent | ||
from environment import Environment | ||
from shogi import Board | ||
from shogi.Move import Move | ||
|
||
|
||
class RandomAgent(Agent): | ||
""" | ||
Random Agent class for shogi. | ||
``` | ||
from shogi import Board | ||
from random_agent import randomAgent | ||
board = Board() | ||
agent = randomAgent.from_board(board) | ||
move: Move = agent.select_action(board) | ||
``` | ||
""" | ||
|
||
def __init__(self, env: Environment, strategy=None): | ||
strategy = "random" | ||
super().__init__(env, strategy) | ||
|
||
def select_action(self) -> Move: | ||
legal_moves = self._env.action_space | ||
return random.choice(legal_moves) | ||
|
||
@classmethod | ||
def from_board(cls, board: Board): | ||
return RandomAgent(Environment(board)) |