Skip to content

Commit

Permalink
Added more tests
Browse files Browse the repository at this point in the history
Fixed coverage.py version 5.0+ issue with Cython plugin according to cython/cython#3515

Signed-off-by: Raragyay <let987let987@gmail.com>
  • Loading branch information
Raragyay committed Jan 7, 2021
1 parent f45bfeb commit f36a154
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 76 deletions.
2 changes: 2 additions & 0 deletions GRGym/environment/environment.pxd
Expand Up @@ -22,6 +22,8 @@ cdef class Environment:

cdef Observation build_observations(self, Player player)

cdef void draw_from_deck(self, Player player, int64_t num_of_cards = *) except *
cdef void draw_from_discard(self, Player player) except *
cdef void discard_card(self, Player player, card_to_discard: int) except *
cdef int64_t try_to_knock(self, Player player)

Expand Down
32 changes: 16 additions & 16 deletions GRGym/environment/environment.pyx
Expand Up @@ -102,11 +102,11 @@ cdef class Environment:
assert wants_to_call == 0 or wants_to_call == 1
if self.current_phase == ActionPhase.CALL_BEFORE_DISCARD:
if wants_to_call and Environment.is_gin(player):
return True, self.get_opponent_deadwood(player) + self.BIG_GIN_BONUS
return True, self.get_opponent_deadwood(player) + get_big_gin_bonus()
elif self.current_phase == ActionPhase.CALL_AFTER_DISCARD:
if wants_to_call:
if Environment.is_gin(player):
return True, self.get_opponent_deadwood(player) + self.GIN_BONUS
return True, self.get_opponent_deadwood(player) + get_gin_bonus()
elif Environment.can_knock(player):
score_delta = self.try_to_knock(player)
return True, score_delta
Expand All @@ -119,20 +119,6 @@ cdef class Environment:
self.discard_card(player, card_to_discard)
return False, 0

def draw_from_deck(self, Player player, num_of_cards: int = 1):
assert self.opponents(player)
assert len(self.deck) >= num_of_cards
for card_val in self.deck[:num_of_cards]:
player.add_card_from_deck(card_val)
self.deck = self.deck[num_of_cards:]
return

def draw_from_discard(self, Player player):
cdef int8_t drawn_card = self.pop_from_discard_pile()
cdef int8_t new_top_discard = player.NO_CARD if self.discard_pile_is_empty() else self.discard_pile[-1]
player.add_card_from_discard(drawn_card, new_top_discard)
self.opponents(player).report_opponent_drew_from_discard(drawn_card, new_top_discard)

cdef Observation build_observations(self, Player player):
"""
Returns the observation object for the given player.
Expand All @@ -146,6 +132,20 @@ cdef class Environment:
observation.deck_size = len(self.deck)
return observation

cdef void draw_from_deck(self, Player player, int64_t num_of_cards = 1) except *:
assert self.opponents(player)
assert len(self.deck) >= num_of_cards
for card_val in self.deck[:num_of_cards]:
player.add_card_from_deck(card_val)
self.deck = self.deck[num_of_cards:]
return

cdef void draw_from_discard(self, Player player) except *:
cdef int8_t drawn_card = self.pop_from_discard_pile()
cdef int8_t new_top_discard = player.NO_CARD if self.discard_pile_is_empty() else self.discard_pile[-1]
player.add_card_from_discard(drawn_card, new_top_discard)
self.opponents(player).report_opponent_drew_from_discard(drawn_card, new_top_discard)

cdef void discard_card(self, Player player, card_to_discard: int) except *:
assert player.has_card(card_to_discard), f"Player does not have the card {card_to_discard}"
cdef int8_t previous_top = player.NO_CARD if self.discard_pile_is_empty() else self.discard_pile[-1]
Expand Down
3 changes: 3 additions & 0 deletions GRGym/simulation/match.py
@@ -1,3 +1,6 @@
import time
from timeit import default_timer

import numpy as np

from GRGym.agent import BaseAgent
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
@@ -1,7 +1,7 @@
atomicwrites==1.4.0
attrs==19.3.0
colorama==0.4.3
coverage==5.1
coverage<5.0
Cython==0.29.19
importlib-metadata==1.6.0
more-itertools==8.3.0
Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -33,6 +33,7 @@ def build_extension(ext_name):
}
# Only add line tracing directive if distutils tracing macro is specified from CLI.
if 'CYTHON_TRACE_NOGIL' in sys.argv:
print('true')
compiler_directives['linetrace'] = True

setup(
Expand Down
18 changes: 17 additions & 1 deletion tests/agent/test_agent.py
@@ -1,10 +1,26 @@
import numpy as np
import pytest

from GRGym.agent import BaseAgent
from GRGym.agent import BaseAgent, RandomAgent


def test_act():
test_agent = BaseAgent()
with pytest.raises(NotImplementedError):
test_agent.act(np.zeros(57))


def test_reset():
test_agent = BaseAgent()
with pytest.raises(NotImplementedError):
test_agent.reset()


def test_random():
test_agent = RandomAgent()
np.random.seed(52)
test_arr = np.random.rand(56)
np.random.seed(52)
given_arr = test_agent.act(np.zeros(57))
np.testing.assert_array_equal(test_arr, given_arr)
assert test_agent.reset() is None # it shouldn't do anything
2 changes: 1 addition & 1 deletion tests/environment/environment/conftest.py
Expand Up @@ -20,7 +20,7 @@ def base_player_class():

@pytest.fixture
def test_env():
return base_env_class()(base_agent_class()())
return base_env_class()()


@pytest.fixture
Expand Down
60 changes: 9 additions & 51 deletions tests/environment/environment/cytest_environment.pyx
Expand Up @@ -36,57 +36,6 @@ def test_can_knock(player_with_cards, np.ndarray cards_in_hand, bint expected):
def test_is_gin(player_with_cards, np.ndarray cards_in_hand, bint expected):
assert Environment.is_gin(player_with_cards(cards_in_hand)) == expected

@pytest.mark.parametrize("actions,expected", retrieve_file_tests(retrieve_float_vector, retrieve_boolean,
idfn_id_expected,
file_names=[
"environment/environment/wants_to_knock_cases.txt"]))
@cython_wrap
def test_wants_to_knock(np.ndarray actions, bint expected):
assert Environment.wants_to_knock(actions) == expected

@pytest.mark.parametrize("actions,expected", retrieve_file_tests(retrieve_float_vector, retrieve_boolean,
idfn_id_expected,
file_names=[
"environment/environment/wants_to_draw_from_deck_cases.txt"]))
@cython_wrap
def test_wants_to_draw_from_deck(np.ndarray actions, bint expected):
assert Environment.wants_to_draw_from_deck(actions) == expected

@cython_wrap
def test_update_score(Environment test_env, Player test_player):
score_limit = test_env.SCORE_LIMIT
assert test_env.update_score(test_player, score_limit // 2) == ActionResult.WON_HAND
assert test_env.update_score(test_player, score_limit) == ActionResult.WON_MATCH
assert test_player.score >= score_limit
test_player.score = 0
assert test_env.update_score(test_player, score_limit == ActionResult.WON_MATCH)

@pytest.mark.parametrize("cards_in_hand,deadwood", retrieve_file_tests(retrieve_nonzero_indices, retrieve_int,
idfn_id_expected,
file_names=["environment/deadwood/td_10.txt"]))
@cython_wrap
def test_score_gin(Environment test_env, Player test_player, player_with_cards, np.ndarray cards_in_hand,
int deadwood):
test_env.player_1 = test_player
test_env.player_2 = player_with_cards(cards_in_hand)
test_player.score = test_env.SCORE_LIMIT - test_env.GIN_BONUS - deadwood
assert test_env.score_gin(test_player) == ActionResult.WON_MATCH
test_player.score = test_env.SCORE_LIMIT - test_env.GIN_BONUS - deadwood - 1
assert test_env.score_gin(test_player) == ActionResult.WON_HAND

@pytest.mark.parametrize("cards_in_hand,deadwood", retrieve_file_tests(retrieve_nonzero_indices, retrieve_int,
idfn_id_expected,
file_names=["environment/deadwood/td_10.txt"]))
@cython_wrap
def test_score_big_gin(Environment test_env, Player test_player, player_with_cards, np.ndarray cards_in_hand,
int deadwood):
test_env.player_1 = test_player
test_env.player_2 = player_with_cards(cards_in_hand)
test_player.score = test_env.SCORE_LIMIT - test_env.BIG_GIN_BONUS - deadwood
assert test_env.score_big_gin(test_player) == ActionResult.WON_MATCH
test_player.score = test_env.SCORE_LIMIT - test_env.BIG_GIN_BONUS - deadwood - 1
assert test_env.score_big_gin(test_player) == ActionResult.WON_HAND

@cython_wrap
def test_opponents(Environment test_env):
cdef Player player_1_1 = Player()
Expand Down Expand Up @@ -121,3 +70,12 @@ def test_discard_pile_is_empty(Environment test_env):
assert i == 0 or not test_env.discard_pile_is_empty()
test_env.discard_pile = np.zeros(i, dtype=np.int8)
assert i == 0 or not test_env.discard_pile_is_empty()

@cython_wrap
def test_repr(Environment test_env):
assert repr(test_env) # make sure no errors

@cython_wrap
def test_get_opponent_deadwood(Environment test_env):
assert Environment.get_deadwood(test_env.player_1) == test_env.get_opponent_deadwood(test_env.player_2)
assert test_env.get_opponent_deadwood(test_env.player_1) == Environment.get_deadwood(test_env.player_2)
12 changes: 6 additions & 6 deletions tests/environment/environment/cytest_environment_properties.pyx
Expand Up @@ -6,8 +6,8 @@ from GRGym.environment.player cimport Player
from GRGym.environment.environment cimport Environment

@cython_wrap
def test_score_limit(Environment test_env, test_agent):
cdef Environment other_test_env = Environment(test_agent)
def test_score_limit(Environment test_env):
cdef Environment other_test_env = Environment()
assert other_test_env.SCORE_LIMIT == test_env.SCORE_LIMIT
test_env.SCORE_LIMIT += 1
assert other_test_env.SCORE_LIMIT == test_env.SCORE_LIMIT
Expand All @@ -17,8 +17,8 @@ def test_score_limit(Environment test_env, test_agent):
assert other_test_env.SCORE_LIMIT == test_env.SCORE_LIMIT

@cython_wrap
def test_gin_bonus(Environment test_env, test_agent):
cdef Environment other_test_env = Environment(test_agent)
def test_gin_bonus(Environment test_env):
cdef Environment other_test_env = Environment()
assert other_test_env.GIN_BONUS == test_env.GIN_BONUS
test_env.GIN_BONUS += 1
assert other_test_env.GIN_BONUS == test_env.GIN_BONUS
Expand All @@ -28,8 +28,8 @@ def test_gin_bonus(Environment test_env, test_agent):
assert other_test_env.GIN_BONUS == test_env.GIN_BONUS

@cython_wrap
def test_big_gin_bonus(Environment test_env, test_agent):
cdef Environment other_test_env = Environment(test_agent)
def test_big_gin_bonus(Environment test_env):
cdef Environment other_test_env = Environment()
assert other_test_env.BIG_GIN_BONUS == test_env.BIG_GIN_BONUS
test_env.BIG_GIN_BONUS += 1
assert other_test_env.BIG_GIN_BONUS == test_env.BIG_GIN_BONUS
Expand Down
12 changes: 12 additions & 0 deletions tests/test_match.py
@@ -0,0 +1,12 @@
import pytest

from GRGym.agent import RandomAgent
from GRGym.simulation.match import Match
from GRGym.agent import HandBuiltAgent


def test_simulate():
agent_1 = HandBuiltAgent()
agent_2 = HandBuiltAgent()
m = Match(agent_1, agent_2)
m.simulate_matches(1)

0 comments on commit f36a154

Please sign in to comment.