File size: 3,716 Bytes
1c66cf8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""Tests for features/pool.py."""
from __future__ import annotations

from werewolftown.features.pool import (
    pool_known,
    pool_remaining,
    pool_scarcity_bonus,
    scarcity_lambda,
)
from werewolftown.state.game_state import PlayerView


class TestPoolKnown:
    def test_counts_built_hand_opponents(self, make_state):
        state = make_state(
            plots=frozenset({4, 5}),
            built_on={4: "Happy", 5: "Happy"},
            shops=("Happy", "猫天天"),
            other_players={"浩宇": PlayerView(
                name="浩宇", cash=50000,
                plots=frozenset({10}),
                shops=("猫天天", "猫天天"),
            )},
        )
        known = pool_known(state)
        assert known["Happy"] == 3  # 2 built + 1 hand
        assert known["猫天天"] == 3  # 1 hand + 2 opp

    def test_empty_state(self, make_state):
        state = make_state()
        assert pool_known(state) == {}

    def test_only_my_shops(self, make_state):
        state = make_state(shops=("Happy", "Happy", "云小宝"))
        known = pool_known(state)
        assert known["Happy"] == 2
        assert known["云小宝"] == 1


class TestPoolRemaining:
    def test_happy_pool_8_minus_3(self, make_state):
        state = make_state(
            built_on={4: "Happy", 5: "Happy"},
            shops=("Happy",),
            other_players={"浩宇": PlayerView(name="浩宇", cash=50000, plots=frozenset({10}), shops=("Happy",))},
        )
        # CARD_POOL["Happy"] = 8, known = 2 built + 1 hand + 1 opp = 4 → remaining = 4
        assert pool_remaining(state, "Happy") == 4

    def test_full_pool(self, make_state):
        state = make_state()
        assert pool_remaining(state, "Happy") == 8

    def test_zero_when_all_known(self, make_state):
        from werewolftown.state.game_state import PlayerView
        # Happy pool=8, build 4 + hand 2 + opp 2 = 8
        state = make_state(
            built_on={4: "Happy", 5: "Happy", 6: "Happy", 8: "Happy"},
            shops=("Happy", "Happy"),
            other_players={"浩宇": PlayerView(name="浩宇", cash=50000, plots=frozenset({10}), shops=("Happy", "Happy"))},
        )
        assert pool_remaining(state, "Happy") == 0


class TestScarcityLambda:
    def test_pool_le_1(self, make_state, cfg):
        from werewolftown.state.game_state import PlayerView
        # 7 Happy known → remaining=1
        state = make_state(
            built_on={4: "Happy", 5: "Happy", 6: "Happy", 8: "Happy", 9: "Happy"},
            shops=("Happy",),
            other_players={"浩宇": PlayerView(name="浩宇", cash=50000, plots=frozenset({10}), shops=("Happy",))},
        )
        lam = scarcity_lambda(state, "Happy", cfg)
        assert lam == 0.55

    def test_default_lambda(self, make_state, cfg):
        state = make_state()
        lam = scarcity_lambda(state, "Happy", cfg)
        assert lam == 0.25

    def test_r4_lambda(self, make_state, cfg):
        state = make_state(round=4)
        lam = scarcity_lambda(state, "Happy", cfg)
        assert lam == 0.50


class TestPoolScarcityBonus:
    def test_bonus_when_scarce(self, make_state, cfg):
        from werewolftown.state.game_state import PlayerView
        state = make_state(
            built_on={4: "Happy", 5: "Happy", 6: "Happy", 8: "Happy", 9: "Happy"},
            shops=("Happy",),
            other_players={"浩宇": PlayerView(name="浩宇", cash=50000, plots=frozenset({10}), shops=("Happy",))},
        )
        assert pool_scarcity_bonus(state, "Happy", cfg) == 1.5

    def test_no_bonus_when_abundant(self, make_state, cfg):
        state = make_state()
        assert pool_scarcity_bonus(state, "Happy", cfg) == 1.0