Skip to content

Commit

Permalink
feat(hexapawn): add hexapawn
Browse files Browse the repository at this point in the history
* feat: WIP

* feat: add WIP game impl

* feat: add hexapawn
  • Loading branch information
Entze authored Dec 20, 2023
1 parent bfb543a commit b45208c
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 0 deletions.
18 changes: 18 additions & 0 deletions prof/prof_common_hexapawn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pathlib

import pyggp.game_description_language as gdl
from pyggp.engine_primitives import Role
from pyggp.interpreters import ClingoInterpreter, ClingoRegroundingInterpreter

hexapawn_str: str = pathlib.Path("../src/games/hexapawn.gdl").read_text()

hexapawn_ruleset: gdl.Ruleset = gdl.parse(hexapawn_str)

hexapawn_interpreter = ClingoInterpreter.from_ruleset(hexapawn_ruleset)

hexapawn_init_state = hexapawn_interpreter.get_init_state()

hexapawn_roles = hexapawn_interpreter.get_roles()

hexapawn_white = Role(gdl.Subrelation(gdl.Relation("white")))
hexapawn_black = Role(gdl.Subrelation(gdl.Relation("black")))
40 changes: 40 additions & 0 deletions prof/profile_hexapawn_book_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import sys

from pyggp._caching import flatlen, weighted_len
from pyggp.agents.tree_agents.evaluators import final_goal_normalized_utility_evaluator
from pyggp.books import BookBuilder
from tqdm import trange

from prof.prof_caches import clear_caches, print_cache_info
from prof.prof_common_hexapawn import hexapawn_init_state, hexapawn_interpreter, hexapawn_white

print()
print_cache_info(hexapawn_interpreter)
clear_caches(hexapawn_interpreter)
print()

builder = BookBuilder(
interpreter=hexapawn_interpreter,
role=hexapawn_white,
evaluator=final_goal_normalized_utility_evaluator,
min_value=0.0,
max_value=1.0,
)

for _ in trange(1_000_000_000):
builder.step()

print("Size:", len(builder.book))
print("Queue:", len(builder._queue))
print(
"Estimated size: ",
flatlen(builder.book.keys(), factor=128) + weighted_len(builder.book, factor=sys.getsizeof(1.0)),
)
print("Done: ", builder.done)
book = builder()
if builder.done:
print("white:", book[hexapawn_init_state])


print()
print_cache_info(hexapawn_interpreter)
18 changes: 18 additions & 0 deletions prof/profile_hexapawn_count_states.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from collections import deque

from prof.prof_common_hexapawn import hexapawn_init_state, hexapawn_interpreter

hexapawn_states = [hexapawn_init_state]

hexapawn_queue = deque(hexapawn_states)

while hexapawn_queue:
print("Queue:", len(hexapawn_queue), "States:", len(hexapawn_states))
hexapawn_state = hexapawn_queue.popleft()
for turn, state in hexapawn_interpreter.get_all_next_states(hexapawn_state):
if state in hexapawn_states:
continue
hexapawn_queue.append(state)
hexapawn_states.append(state)

print("Queue:", len(hexapawn_queue), "States:", len(hexapawn_states))
100 changes: 100 additions & 0 deletions src/games/hexapawn.gdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@

role(white). role(black).

file(a). file(b). file(c).
rank(1). rank(2). rank(3).

succ(a, b). succ(b, c).
succ(1, 2). succ(2, 3).

cell((F, R)) :- file(F), rank(R).

init(occupies_cell(white, (a, 1))).
init(occupies_cell(white, (b, 1))).
init(occupies_cell(white, (c, 1))).
init(occupies_cell(black, (a, 3))).
init(occupies_cell(black, (b, 3))).
init(occupies_cell(black, (c, 3))).
init(control(white)).

cell_orthogonalneighbor((F,R), (F,R1)) :- file(F), rank(R), rank(R1), succ(R, R1).
cell_orthogonalneighbor((F,R), (F1,R)) :- file(F), file(F1), rank(R), succ(F, F1).
cell_orthogonalneighbor(C1, C2) :- cell_orthogonalneighbor(C2, C1).

cell_diagonalneighbor((F,R), (F1,R1)) :- file(F), file(F1), rank(R), rank(R1), succ(F, F1), succ(R, R1).
cell_diagonalneighbor((F,R), (F1,R1)) :- file(F), file(F1), rank(R), rank(R1), succ(F1, F), succ(R, R1).
cell_diagonalneighbor((F,R), (F1,R1)) :- file(F), file(F1), rank(R), rank(R1), succ(F, F1), succ(R1, R).
cell_diagonalneighbor((F,R), (F1,R1)) :- file(F), file(F1), rank(R), rank(R1), succ(F1, F), succ(R1, R).

cell_neighbor(C1, C2) :- cell_orthogonalneighbor(C1, C2).
cell_neighbor(C1, C2) :- cell_diagonalneighbor(C1, C2).

action(move(C1,C2)) :- cell(C1), cell(C2), cell_neighbor(C1, C2).

next(control(R1)) :-
true(control(R2)),
role(R1), role(R2),
distinct(R1, R2).

next(occupies_cell(R, C)) :-
true(occupies_cell(R, C)),
does(_, move(C1, C2)),
cell(C), cell(C1), cell(C2),
distinct(C, C1),
distinct(C, C2).

next(occupies_cell(R, C2)) :-
true(occupies_cell(R, C1)),
does(R, move(C1, C2)),
role(R),
cell(C1), cell(C2).

legal(R, move(C1, C2)) :-
true(occupies_cell(R, C1)),
not true(occupies_cell(_, C2)),
role(R),
cell(C1), cell(C2),
cell_orthogonalneighbor(C1, C2).

legal(R1, move(C1, C2)) :-
true(occupies_cell(R1, C1)),
true(occupies_cell(R2, C2)),
role(R1), role(R2),
cell(C1), cell(C2),
distinct(R1, R2),
cell_diagonalneighbor(C1, C2).

goal(white, 1) :-
true(occupies_cell(white, (_, 3))).

goal(black, -1) :-
true(occupies_cell(white, (_, 3))).

goal(black, 1) :-
true(occupies_cell(black, (_, 1))).

goal(white, -1) :-
true(occupies_cell(black, (_, 1))).

goal(R1, 1) :-
true(control(R2)),
not legal(R2, _),
role(R1), role(R2),
distinct(R1, R2).

goal(R2, -1) :-
true(control(R2)),
not legal(R2, _),
role(R1), role(R2),
distinct(R1, R2).

terminal :-
true(occupies_cell(white, (_, 3))).

terminal :-
true(occupies_cell(black, (_, 1))).

terminal :-
true(control(R)),
not legal(R, _),
role(R).

0 comments on commit b45208c

Please sign in to comment.