faceoffs and functioning test game
This commit is contained in:
parent
1c6a5400a5
commit
a317e079d6
51
game.py
51
game.py
|
@ -1,6 +1,6 @@
|
||||||
import random, team, player, os
|
import random, team, player, os, math
|
||||||
from team import Team
|
from team import Team
|
||||||
from player import Player, AtkAction, DefAction
|
from player import Player, AtkAction, DefAction, Skater, Goalie
|
||||||
from skillContests import SkillContestParams, Situations
|
from skillContests import SkillContestParams, Situations
|
||||||
from attributes import normalDis
|
from attributes import normalDis
|
||||||
from hocUtils import RinkGraph
|
from hocUtils import RinkGraph
|
||||||
|
@ -21,7 +21,8 @@ class Game(object):
|
||||||
self.awayZones = RinkGraph(edgeFilename=DEFAULTRINKFILENAME)
|
self.awayZones = RinkGraph(edgeFilename=DEFAULTRINKFILENAME)
|
||||||
self.homeZones = RinkGraph(edgeFilename=DEFAULTRINKFILENAME)
|
self.homeZones = RinkGraph(edgeFilename=DEFAULTRINKFILENAME)
|
||||||
self.currentZone = None
|
self.currentZone = None
|
||||||
self.faceoff = FaceoffDot.Center
|
self.faceoffSpot = FaceoffDot.Center
|
||||||
|
self.playStopped = True
|
||||||
|
|
||||||
self.lineSize = 5
|
self.lineSize = 5
|
||||||
if len(awayTeam.roster) != 10 or len(homeTeam.roster) != 10 or threes:
|
if len(awayTeam.roster) != 10 or len(homeTeam.roster) != 10 or threes:
|
||||||
|
@ -30,11 +31,11 @@ class Game(object):
|
||||||
self.goalieHome = self.home.chooseGoalie()
|
self.goalieHome = self.home.chooseGoalie()
|
||||||
self.goalieAway = self.away.chooseGoalie()
|
self.goalieAway = self.away.chooseGoalie()
|
||||||
|
|
||||||
self.positionInPossession = None
|
self.positionInPossession = None #use SkaterPosition enum
|
||||||
self.teamInPossession = None
|
self.teamInPossession = None
|
||||||
|
|
||||||
self.skatersHome = [] #LW LD C RD RW, use the SkaterPosition enum for indexing.
|
self.skatersHome = self.home.roster[:5] #LW LD C RD RW, EA; use the SkaterPosition enum for indexing. Threes uses left winger, left defenseman, center.
|
||||||
self.skatersAway = []
|
self.skatersAway = self.away.roster[:5]
|
||||||
|
|
||||||
self.penaltyBoxAway = []
|
self.penaltyBoxAway = []
|
||||||
self.penaltyBoxHome = []
|
self.penaltyBoxHome = []
|
||||||
|
@ -42,22 +43,35 @@ class Game(object):
|
||||||
self.pulledGoalieHome = False
|
self.pulledGoalieHome = False
|
||||||
|
|
||||||
self.period = 1
|
self.period = 1
|
||||||
self.clock = 60*20 #clock will be given in seconds
|
self.clock = 60*20 #Time remaining in period, given in seconds
|
||||||
|
|
||||||
self.eventLog = []
|
self.eventLog = []
|
||||||
|
|
||||||
def defendingTeam(self):
|
def defendingTeam(self):
|
||||||
if teamInPossession == self.home:
|
if self.teamInPossession == self.home:
|
||||||
return self.away
|
return self.away
|
||||||
else:
|
else:
|
||||||
return self.home
|
return self.home
|
||||||
|
|
||||||
def attackingTeam(self):
|
def attackingTeam(self):
|
||||||
"""Alias for teamInPossession, to match defendingTeam()"""
|
"""Alias for teamInPossession, to match defendingTeam()"""
|
||||||
return teamInPossession
|
return self.teamInPossession
|
||||||
|
|
||||||
def homeAttacking(self):
|
def homeAttacking(self):
|
||||||
return teamInPossession == self.home
|
return self.teamInPossession == self.home
|
||||||
|
|
||||||
|
def skatersInPossession(self):
|
||||||
|
return self.skatersHome if self.homeAttacking() else self.skatersAway
|
||||||
|
|
||||||
|
def clockToMinutesSeconds(self):
|
||||||
|
"""Returns a string MM:SS elapsed in period."""
|
||||||
|
elapsedSeconds = 60*20 - self.clock if self.clock >= 0 else 60*20
|
||||||
|
minutes = str(int(math.modf(elapsedSeconds/60)[1]))
|
||||||
|
seconds = str(elapsedSeconds % 60)
|
||||||
|
if len(seconds) == 1:
|
||||||
|
seconds = f"0{seconds}"
|
||||||
|
return f"{minutes}:{seconds}"
|
||||||
|
|
||||||
|
|
||||||
def currentSituation(self):
|
def currentSituation(self):
|
||||||
skatersH = self.lineSize + self.pulledGoalieHome - len(self.penaltyBoxHome)
|
skatersH = self.lineSize + self.pulledGoalieHome - len(self.penaltyBoxHome)
|
||||||
|
@ -83,6 +97,22 @@ class Game(object):
|
||||||
defRoll = normalDis(defValue, defValue/2, 0)
|
defRoll = normalDis(defValue, defValue/2, 0)
|
||||||
return atkRoll-defRoll > 0
|
return atkRoll-defRoll > 0
|
||||||
|
|
||||||
|
def faceoff(self, awayPlayer:Skater, homePlayer:Skater):
|
||||||
|
"""Hold a faceoff! True indicates home win, False is away win."""
|
||||||
|
faceoffSkills = [('Dex',50),('Sti',50),('Pas', 10)]
|
||||||
|
params = SkillContestParams(faceoffSkills, faceoffSkills)
|
||||||
|
return self.skillContest(homePlayer, awayPlayer, params) if random.random() > 0.4 else random.sample([True, False], 1)[0]
|
||||||
|
|
||||||
|
def event(self):
|
||||||
|
"""Meat and potatoes. Everything that happens is a direct result of this being called."""
|
||||||
|
if self.playStopped: #need a faceoff
|
||||||
|
self.teamInPossession = self.home if self.faceoff(self.skatersAway[SkaterPosition.C.value], self.skatersHome[SkaterPosition.C.value]) else self.away
|
||||||
|
self.positionInPossession = SkaterPosition(random.sample([0, 1, 1, 3, 3, 4],1)[0]) #wingers are less likely to recieve the faceoff than defensemen
|
||||||
|
self.playStopped = False
|
||||||
|
winningPlayer = self.skatersInPossession()[SkaterPosition.C.value]
|
||||||
|
self.eventLog.append(f"{self.clockToMinutesSeconds()} - {self.teamInPossession.shortname} {str(winningPlayer)} wins faceoff.")
|
||||||
|
self.clock -= random.randint(2,5)
|
||||||
|
|
||||||
class FaceoffDot(Enum):
|
class FaceoffDot(Enum):
|
||||||
"""All orientations are given from the perspective of the defending team."""
|
"""All orientations are given from the perspective of the defending team."""
|
||||||
AwayZoneLeft = -4
|
AwayZoneLeft = -4
|
||||||
|
@ -102,3 +132,4 @@ class SkaterPosition(Enum):
|
||||||
C = 2
|
C = 2
|
||||||
RD = 3
|
RD = 3
|
||||||
RW = 4
|
RW = 4
|
||||||
|
EA = 5
|
42
hocTests.py
42
hocTests.py
|
@ -11,7 +11,7 @@ class AttributeTest(object):
|
||||||
|
|
||||||
self.fakeGame = game.Game(None, None)
|
self.fakeGame = game.Game(None, None)
|
||||||
|
|
||||||
self.params = skillContests.SkillContestParams(self.atkAction, self.defAction)
|
self.params = skillContests.SkillContestParams().actionCheck(self.atkAction, self.defAction)
|
||||||
|
|
||||||
def lowStats(self):
|
def lowStats(self):
|
||||||
"""Tests attacker and defender with minimum stats."""
|
"""Tests attacker and defender with minimum stats."""
|
||||||
|
@ -87,3 +87,43 @@ class AttributeTest(object):
|
||||||
print(self.defPlayer.getAttribute(attr))
|
print(self.defPlayer.getAttribute(attr))
|
||||||
print(f"Success rate: {str(round(success/total*100,2))}%")
|
print(f"Success rate: {str(round(success/total*100,2))}%")
|
||||||
print("-------")
|
print("-------")
|
||||||
|
|
||||||
|
|
||||||
|
class TestGame(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
awayRoster = [
|
||||||
|
player.Player("Laika", 93),
|
||||||
|
player.Player("Vivi", 16),
|
||||||
|
player.Player("Jorts", 75),
|
||||||
|
player.Player("Yuki", 23),
|
||||||
|
player.Player("Konecny", 96),
|
||||||
|
player.Player("Laika", 93),
|
||||||
|
player.Player("Vivi", 16),
|
||||||
|
player.Player("Jorts", 75),
|
||||||
|
player.Player("Yuki", 23),
|
||||||
|
player.Player("Konecny", 96)
|
||||||
|
]
|
||||||
|
homeRoster = [
|
||||||
|
player.Player("Landeskog", 92),
|
||||||
|
player.Player("Byram", 4),
|
||||||
|
player.Player("MacKinnon", 29),
|
||||||
|
player.Player("Makar", 8),
|
||||||
|
player.Player("Rantanen", 96),
|
||||||
|
player.Player("Landeskog", 92),
|
||||||
|
player.Player("Byram", 4),
|
||||||
|
player.Player("MacKinnon", 29),
|
||||||
|
player.Player("Makar", 8),
|
||||||
|
player.Player("Rantanen", 96)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
aTeam = team.Team(awayRoster, [player.Player('Artemis', 17)], "Jorts Butter", "BTR")
|
||||||
|
hTeam = team.Team(homeRoster, [player.Player('Kuemper', 35)], "Colorado Avalanche", "COL")
|
||||||
|
self.Game = game.Game(aTeam, hTeam)
|
||||||
|
|
||||||
|
def faceoffTest(self):
|
||||||
|
for i in range(0,8):
|
||||||
|
self.Game.playStopped = True
|
||||||
|
foResult = self.Game.event()
|
||||||
|
pass
|
16
hocUtils.py
16
hocUtils.py
|
@ -129,3 +129,19 @@ class RinkGraph(object):
|
||||||
if nodeDic['adjacent']:
|
if nodeDic['adjacent']:
|
||||||
adjacents.append(otherNodeName)
|
adjacents.append(otherNodeName)
|
||||||
return adjacents
|
return adjacents
|
||||||
|
|
||||||
|
def shotDanger(self, nodeName):
|
||||||
|
"""Returns an int indicating the danger of a shot from that zone. 0 is no danger, 100 is 26-Offensive Low Slot"""
|
||||||
|
if isinstance(nodeName, int):
|
||||||
|
nodeName = str(nodeName)
|
||||||
|
|
||||||
|
if int(nodeName[1]) < 5:
|
||||||
|
return 0
|
||||||
|
elif nodeName == '26':
|
||||||
|
return 100
|
||||||
|
elif nodeName == '25':
|
||||||
|
return 70
|
||||||
|
elif nodeName[0] in ['1','3'] or nodeName == '27': #27 is included for tuck/michigan
|
||||||
|
return 40
|
||||||
|
else:
|
||||||
|
return 20
|
Loading…
Reference in a new issue