updated roles, init tests, added states
This commit is contained in:
50
README.md
50
README.md
@@ -1,3 +1,53 @@
|
||||
# PyWerwolf
|
||||
|
||||
Trying to rebuild [https://github.com/foin137/werwolfonline.eu](https://github.com/foin137/werwolfonline.eu) in python
|
||||
|
||||
|
||||
## Phases of the game
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
[*] --> WaitingForPlayers: Created
|
||||
WaitingForPlayers : Show the game id/link
|
||||
WaitingForPlayers : Create game in Database
|
||||
WaitingForPlayers : Allow setting of rules
|
||||
|
||||
WaitingForPlayers --> StartGame: len(Players)>=len(special roles) && start && num_werewolfes > 1
|
||||
WaitingForPlayers --> WaitingForPlayers: start && (len(Players)<len(special roles) || num_werewolfes < 1)
|
||||
StartGame : Assign Player Roles
|
||||
StartGame : Show Introduction
|
||||
|
||||
state GameHasCupin <<choice>>
|
||||
state NightPhaseCupin <<fork>>
|
||||
StartGame --> GameHasCupin : all ready
|
||||
GameHasCupin --> NightPhaseCupin: Game has Cupin
|
||||
GameHasCupin --> NightPhaseMain: no Cupin
|
||||
NightPhaseMain : Werewolfes awake & select (vote) their victim
|
||||
NightPhaseMain : Seer/Spy/Protector/ParanormalInvestigator awaken & access feat
|
||||
NightPhaseMain : sleep & confirm
|
||||
|
||||
|
||||
state NightPhaseCupinEnd <<join>>
|
||||
NightPhaseCupin --> WaitToContinueCupin: !Cupin
|
||||
NightPhaseCupin --> SelectLovedOnes: Cupin
|
||||
WaitToContinueCupin --> NightPhaseCupinEnd
|
||||
SelectLovedOnes --> NightPhaseCupinEnd: selected and confirmed loved ones
|
||||
|
||||
state NightPhaseLovedOnes <<fork>>
|
||||
state NightPhaseLovedOnesEnd <<fork>>
|
||||
NightPhaseCupinEnd --> NightPhaseLovedOnes
|
||||
NightPhaseLovedOnes --> LovedOnesAwake: Selected Loved Ones
|
||||
NightPhaseLovedOnes --> WaitForLovedOnes: other
|
||||
LovedOnesAwake --> NightPhaseLovedOnesEnd: ready
|
||||
WaitForLovedOnes --> NightPhaseLovedOnesEnd
|
||||
|
||||
NightPhaseLovedOnesEnd --> NightPhaseMain : all ready
|
||||
NightPhaseMain --> NightPhaseLate : Witch/Leaderwolf && voted && actions done and all ready
|
||||
|
||||
NightPhaseLate: LeaderWolf selects victim to convert
|
||||
NightPhaseLate: witch is allowed to select heal/murder
|
||||
|
||||
NightPhaseMain --> ShowDead: no Witch/Leaderwolf && voted && actions done and all ready
|
||||
NightPhaseLate --> ShowDead: actions taken
|
||||
@enduml
|
||||
```
|
||||
|
||||
@@ -1,3 +1,60 @@
|
||||
import models
|
||||
from pywerwolf import models
|
||||
import typing as t
|
||||
import uuid
|
||||
|
||||
|
||||
class Game(object):
|
||||
state: models.GameState
|
||||
|
||||
def __init__(self, game_id: t.Union[str, uuid.UUID] = None):
|
||||
if game_id is None:
|
||||
self.create_new_game_state()
|
||||
else:
|
||||
self.load_game_state(game_id)
|
||||
|
||||
def create_new_game_state(self):
|
||||
pass
|
||||
|
||||
def load_game_state(self, game_id: t.Union[str, uuid.UUID]):
|
||||
pass
|
||||
|
||||
def valid_game(self):
|
||||
# check if game has been created or loaded
|
||||
return True
|
||||
|
||||
def check_victory(self):
|
||||
"""check for a winner of the current game"""
|
||||
if not self.valid_game():
|
||||
return None
|
||||
|
||||
if self.state.currentPhase == models.GamePhase.Award:
|
||||
return True
|
||||
|
||||
if sum(1 for _ in self.werewolfes) > 0:
|
||||
if sum(1 for _ in self.villagers) <= 0:
|
||||
return models.RoleGroup.Werewolfs
|
||||
pass
|
||||
else:
|
||||
return models.RoleGroup.Villagers
|
||||
|
||||
if sum(1 for _ in self.player_alive) == 2:
|
||||
living = list(self.player_alive)
|
||||
if living[0].lovedOne == living[1]:
|
||||
return models.RoleGroup.LovedOnes
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def player_alive(self):
|
||||
"""Generator for players still alive"""
|
||||
return filter(lambda x: x.alive, self.state.players)
|
||||
|
||||
@property
|
||||
def werewolfes(self):
|
||||
"""Generator for players that are werewolfes"""
|
||||
return filter(models.Player.isWerwolf, self.player_alive)
|
||||
|
||||
@property
|
||||
def villagers(self):
|
||||
"""Generator for players that are villagers"""
|
||||
return filter(not (models.Player.isWerwolf), self.player_alive)
|
||||
|
||||
@@ -21,6 +21,13 @@ class GamePhase(enum.Enum):
|
||||
PollResult = enum.auto()
|
||||
Award = enum.auto()
|
||||
|
||||
class RoleGroup(enum.Enum):
|
||||
NoGroup = enum.auto()
|
||||
Villagers = enum.auto()
|
||||
Werewolfs = enum.auto()
|
||||
LovedOnes = enum.auto()
|
||||
|
||||
|
||||
class Roles(enum.Enum):
|
||||
NoRole = enum.auto()
|
||||
Villager = enum.auto()
|
||||
@@ -31,35 +38,52 @@ class Roles(enum.Enum):
|
||||
Cupid = enum.auto()
|
||||
Protector = enum.auto()
|
||||
ParanormalInvestigator = enum.auto()
|
||||
Lycantrop = enum.auto()
|
||||
Lycantroph = enum.auto()
|
||||
Spy = enum.auto()
|
||||
Murder = enum.auto()
|
||||
Pacifist = enum.auto()
|
||||
OldMan = enum.auto()
|
||||
Murder = enum.auto()
|
||||
Leaderwolf = enum.auto()
|
||||
|
||||
@classmethod
|
||||
def isWerwolf(cls, role: Roles):
|
||||
return role in [cls.Werewolf, cls.Leaderwolf]
|
||||
|
||||
@classmethod
|
||||
def getGroup(cls, role: Roles):
|
||||
return RoleGroup.Werewolfs if role in [cls.Werewolf, cls.Leaderwolf] else RoleGroup.Villagers
|
||||
|
||||
class Rules(object):
|
||||
showRoles: bool #`charaktereAufdecken` INT ( 2 ) DEFAULT 0,
|
||||
passMajor: bool #`buergermeisterWeitergeben` INT ( 2 ) DEFAULT 0,
|
||||
seerSeesIdentity: bool #`seherSiehtIdentitaet` INT ( 2 ) DEFAULT 1,
|
||||
roleCount: t.Dict[Roles, int]
|
||||
#`werwolfzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`hexenzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`seherzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`jaegerzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`amorzahl` INT ( 2 ) DEFAULT 0 ,
|
||||
#`beschuetzerzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`parErmZahl` INT (5) DEFAULT 0 ,
|
||||
#`lykantrophenzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`spionezahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`idiotenzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`pazifistenzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`altenzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
#`urwolfzahl` INT ( 5 ) DEFAULT 0 ,
|
||||
werewolfes: int
|
||||
witches: int
|
||||
seers: int
|
||||
hunters: int
|
||||
cupids: int
|
||||
protectors: int
|
||||
paranormals: int
|
||||
lycantrophs: int
|
||||
spys: int
|
||||
murders: int
|
||||
pacifists: int
|
||||
oldmans: int
|
||||
leaderwolfs: int
|
||||
randomSelect: bool #`zufaelligeAuswahl` INT ( 2 ) DEFAULT 0 ,
|
||||
randomBonus: int #`zufaelligeAuswahlBonus` INT ( 5 ) DEFAULT 0 ,
|
||||
unanimously: bool #`werwolfeinstimmig` INT ( 2 ) DEFAULT 1 ,
|
||||
timer_unanimously: int
|
||||
timer_unanimously_per_wolf: int
|
||||
timer_unsuccessfull: int
|
||||
timer_unsuccessfull_per_wolf: int
|
||||
timer_accusation: int
|
||||
timer_accusation_per_player: int
|
||||
timer_votation: int
|
||||
timer_votation_per_player: int
|
||||
timer_inactivity: int
|
||||
timer_inactivity_per_player: int
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -74,6 +98,10 @@ class Player(object):
|
||||
diedInRound: int
|
||||
accusedBy: "Player"
|
||||
|
||||
@property
|
||||
def isWerwolf(self):
|
||||
return Roles.isWerwolf(self.role)
|
||||
|
||||
|
||||
# `wahlAuf` INT ( 5 ) DEFAULT -1 ,
|
||||
# `angeklagtVon` INT ( 5 ) DEFAULT -1 ,
|
||||
@@ -92,29 +120,11 @@ class Player(object):
|
||||
# `countdownBis` INT (10) DEFAULT 0 ,
|
||||
# `countdownAb` INT (10) DEFAULT 0 ,
|
||||
|
||||
|
||||
class Game(object):
|
||||
class GameState(object):
|
||||
currentPhase: GamePhase #`spielphase` INT( 5 ) DEFAULT 0,
|
||||
gameRound: int
|
||||
rules: Rules
|
||||
log: t.List[str]
|
||||
players: t.List[Player]
|
||||
#`werwolfopfer` INT ( 5 ) DEFAULT -1 ,
|
||||
#`werwolftimer1` INT ( 10 ) DEFAULT 60 ,
|
||||
#`werwolfzusatz1` INT ( 10 ) DEFAULT 4 ,
|
||||
#`werwolftimer2` INT ( 10 ) DEFAULT 50 ,
|
||||
#`werwolfzusatz2` INT ( 10 ) DEFAULT 3 ,
|
||||
#`dorftimer` INT ( 10 ) DEFAULT 550 ,
|
||||
#`dorfzusatz` INT ( 10 ) DEFAULT 10 ,
|
||||
#`dorfstichwahltimer` INT ( 10 ) DEFAULT 200 ,
|
||||
#`dorfstichwahlzusatz` INT ( 10 ) DEFAULT 5 ,
|
||||
#`inaktivzeit` INT ( 10 ) DEFAULT 40 ,
|
||||
#`inaktivzeitzusatz` INT ( 10 ) DEFAULT 0 ,
|
||||
#`tagestext` TEXT ,
|
||||
#`nacht` INT ( 5 ) DEFAULT 1 ,
|
||||
#`log` LONGTEXT ,
|
||||
#`list_lebe` LONGTEXT,
|
||||
#`list_lebe_aktualisiert` BIGINT DEFAULT 0,
|
||||
#`list_tot` LONGTEXT,
|
||||
#`list_tot_aktualisiert` BIGINT DEFAULT 0,
|
||||
#`waiting_for_others_time` BIGINT,
|
||||
#`letzterAufruf` BIGINT
|
||||
|
||||
|
||||
@@ -54,12 +54,18 @@ texts = {
|
||||
models.Roles.Cupid: "Armor",
|
||||
models.Roles.Protector: "Beschützer/in",
|
||||
models.Roles.ParanormalInvestigator: "Paranormaler Ermittler",
|
||||
models.Roles.Lycantrop: "Lykantroph/in",
|
||||
models.Roles.Lycantroph: "Lykantroph/in",
|
||||
models.Roles.Spy: "Spion/in",
|
||||
models.Roles.Murder: "Mordlustige(r)",
|
||||
models.Roles.Pacifist: "Pazifist/in",
|
||||
models.Roles.OldMan: "Der/Die Alte",
|
||||
models.Roles.Leaderwolf: "Urwolf",
|
||||
}
|
||||
},
|
||||
"role_group":{
|
||||
"de": {
|
||||
True : "Werwölfe",
|
||||
False: "Dorfbewohner"
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
23
setup.py
Normal file
23
setup.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import setuptools
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setuptools.setup(
|
||||
name="pywerwolf",
|
||||
version="0.0.1",
|
||||
author="Matthias Bilger",
|
||||
author_email="matthias@bilger.info",
|
||||
description="A Python implementation of Werewolf/Mafia game",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/m42e/pywerwolf",
|
||||
license="GPL",
|
||||
packages=setuptools.find_packages(), # Required
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
'License :: Other/Proprietary License',
|
||||
],
|
||||
python_requires='>=3.6',
|
||||
)
|
||||
8
tests/test_game.py
Normal file
8
tests/test_game.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import pytest
|
||||
|
||||
import pywerwolf
|
||||
import pywerwolf.gamelogic as gl
|
||||
|
||||
def test_game_init():
|
||||
g = gl.Game()
|
||||
|
||||
Reference in New Issue
Block a user