from PlasmaServer import *
heekTables = [ ] # an array of heekGames for the tables we have running
kNone = 0
kRock = 1
kPaper = 2
kScissors = 3
class heekPlayer :
def __init__ ( self ) :
self . ID = - 1
self . key = None
self . pos = - 1
self . choice = kNone
self . rocksWon = 0
self . papersWon = 0
self . scissorsWon = 0
self . roundsWon = 0
self . curRoundScore = 0
self . points = - 1
self . isPlaying = 0
self . name = " "
self . gamePlaying = None # the heekGame we are currently playing
self . scoreDict = { ( kRock , kRock ) : 0 ,
( kRock , kPaper ) : - 1 ,
( kRock , kScissors ) : 1 ,
( kRock , kNone ) : 0 ,
( kPaper , kRock ) : 1 ,
( kPaper , kPaper ) : 0 ,
( kPaper , kScissors ) : - 1 ,
( kPaper , kNone ) : 0 ,
( kScissors , kRock ) : - 1 ,
( kScissors , kPaper ) : 1 ,
( kScissors , kScissors ) : 0 ,
( kScissors , kNone ) : 0 ,
( kNone , kNone ) : 0 ,
( kNone , kRock ) : 0 ,
( kNone , kPaper ) : 0 ,
( kNone , kScissors ) : 0
}
def ScoreAgainst ( self , other ) :
return self . scoreDict [ ( self . choice , other . choice ) ]
def ResetGame ( self ) :
self . choice = kNone
self . rocksWon = 0
self . papersWon = 0
self . scissorsWon = 0
self . curRoundScore = 0
self . isPlaying = 0
def ResetRound ( self ) :
self . curRoundScore = 0
self . choice = kNone
def SendMessage ( self , contents ) :
msg = ptPythonMsg ( )
msg . setKey ( self . key )
msg . setContents ( str ( contents ) )
msg . send ( self . ID )
def CompareRoundScores ( player1 , player2 ) :
if player1 . curRoundScore < player2 . curRoundScore :
return - 1
if player1 . curRoundScore > player2 . curRoundScore :
return 1
return 0
class heekGame :
def __init__ ( self ) :
self . ID = - 1
self . playerList = [ ]
self . countdownStarted = 0
self . winners = [ ]
self . pot = 0
self . agePlayers = [ ] # a list of all people in the age, tuple where 0 is ID and 1 is Key
self . queueCleanup = [ ] # do we need to send a cleanup message to the first person to link in?
def PlayerIDInGame ( self , ID ) :
for player in self . playerList :
if player . ID == ID :
return 1
return 0
def PlayerKeyInGame ( self , key ) :
for player in self . playerList :
if player . key == key :
return 1
return 0
def SendToAll ( self , message ) :
for player in self . playerList :
player . SendMessage ( message )
def SendWelcomeMsg ( self , name , points ) :
self . SendToAll ( " PlrWelcome " + str ( points ) + ' ' + str ( self . CalculateAnte ( points ) ) + ' ' + name )
def SendStatusMsg ( self , player ) :
player . SendMessage ( " Points " + str ( player . points ) + ' ' + str ( self . CalculateAnte ( player . points ) ) )
def CalculateRank ( self , points ) :
if points == 0 :
return 0
gamesWinToRank = 100 # number of 1v1 games against same rank to level
rank = 1
curPoints = gamesWinToRank
while 1 :
curPoints + = rank * gamesWinToRank
if points < = curPoints :
return rank
rank + = 1
def CalculateAnte ( self , points ) :
return self . CalculateRank ( points )
def RewardRoundWinners ( self ) :
for winner in self . winners :
winner . roundsWon + = 1
lightNum = 0
if winner . choice == kRock :
winner . rocksWon + = 1
lightNum = winner . rocksWon
elif winner . choice == kPaper :
winner . papersWon + = 1
lightNum = winner . papersWon
elif winner . choice == kScissors :
winner . scissorsWon + = 1
lightNum = winner . scissorsWon
if lightNum == 0 : # shouldn't happen, but just in case
print " ID: " + str ( self . ID ) + " lightNum is 0 for some reason...len(winners)= " + str ( len ( self . winners ) ) + " , winner.choice= " + str ( winner . choice )
print " ID: " + str ( self . ID ) + " len(playerList)= " + str ( len ( self . playerList ) ) + " , winner.ID= " + str ( winner . ID ) + " , winner.pos= " + str ( winner . pos )
return
winner . SendMessage ( " Win " + str ( winner . choice ) )
if lightNum < 3 :
light = ( winner . choice - 1 ) * 2 + ( lightNum - 1 )
winner . SendMessage ( " LightOn " + str ( light ) )
elif lightNum == 3 :
light1 = ( winner . choice - 1 ) * 2
light2 = light1 + 1
winner . SendMessage ( " Flash " + str ( light1 ) )
winner . SendMessage ( " Flash " + str ( light2 ) )
losers = [ player for player in self . playerList if not player in self . winners ]
for loser in losers :
loser . SendMessage ( " Lose " + str ( loser . choice ) )
def ComputeRoundScores ( self ) :
cnt = len ( self . playerList )
#if cnt == 1: # for single-player only
#self.playerList[0].curRoundScore = 1
for i in range ( cnt - 1 ) :
player1 = self . playerList [ i ]
for j in range ( i + 1 , cnt ) :
player2 = self . playerList [ j ]
player1 . curRoundScore + = player1 . ScoreAgainst ( player2 )
player2 . curRoundScore + = player2 . ScoreAgainst ( player1 )
def PickRoundWinners ( self ) :
rwCopy = self . playerList
rwCopy . sort ( CompareRoundScores )
big = rwCopy [ len ( rwCopy ) - 1 ] . curRoundScore
if big > 0 :
self . winners = [ winner for winner in rwCopy if winner . curRoundScore == big ]
def PickGameWinners ( self ) :
gameWinners = [ winner for winner in self . winners if winner . rocksWon == 3 or winner . papersWon == 3 or winner . scissorsWon == 3 ]
if ( len ( gameWinners ) < = 1 ) :
return gameWinners
gwCopy = gameWinners
gwCopy . sort ( CompareRoundsWon )
big = gwCopy [ len ( gwCopy ) - 1 ] . roundsWon
if big > 0 :
gameWinners = [ winner for winner in gwCopy if winner . roundsWon == big ]
return gameWinners
def HandlePlayerReady ( self ) :
if not self . countdownStarted :
print " ID: " + str ( self . ID ) + " Starting countdown "
self . SendToAll ( " StartCountdown " )
self . countdownStarted = 1
return
playersReady = [ player for player in self . playerList if player . choice != kNone ]
allReady = ( len ( playersReady ) == len ( self . playerList ) )
if allReady and len ( playersReady ) > 1 :
self . SendToAll ( " StopCountdown " )
def ResetGame ( self ) :
self . winners = [ ]
for player in self . playerList :
player . ResetGame ( )
def ResetRound ( self ) :
self . winners = [ ]
for player in self . playerList :
player . ResetRound ( )
def PlayGame ( self ) :
if not self . countdownStarted :
print " ID: " + str ( self . ID ) + " Extra countdown end message received, ignoring "
return # extra countdown end message, ignore
self . countdownStarted = 0
playersReady = [ player for player in self . playerList if player . choice != kNone ]
if len ( playersReady ) < = 1 :
print " ID: " + str ( self . ID ) + " Only one player was ready, aborting game "
self . ResetRound ( )
self . SendToAll ( " ShowIdleAnimation " )
return
print " ID: " + str ( self . ID ) + " Disabling player ' s interfaces "
self . SendToAll ( " Disable " )
self . ComputeRoundScores ( )
self . PickRoundWinners ( )
self . RewardRoundWinners ( )
def HandleGameWinner ( self ) :
gameWinners = self . PickGameWinners ( )
if len ( gameWinners ) > 0 :
print " ID: " + str ( self . ID ) + " A player has won, letting admin know about it "
x = " init "
if ( gameWinners [ 0 ] . choice == kRock ) : # it might be possible for multiple types to win, will need to check
x = " rock "
elif ( gameWinners [ 0 ] . choice == kPaper ) :
x = " paper "
elif ( gameWinners [ 0 ] . choice == kScissors ) :
x = " scissors "
self . SendToAll ( " GameWin " + x )
pointsToGive = int ( self . pot / len ( gameWinners ) )
self . pot - = pointsToGive * len ( gameWinners )
for winner in gameWinners :
if winner . points != - 1 :
winner . SendMessage ( " SetPoints " + str ( winner . points + pointsToGive ) )
for player in self . playerList :
if player . ID == winner . ID and player . key == winner . key :
player . points + = pointsToGive
break
self . ResetGame ( )
for player in self . playerList :
self . SendStatusMsg ( player )
return 1
return 0
def SendTableState ( self , ID , key ) :
for player in self . playerList :
setupMsg = ptPythonMsg ( )
setupMsg . setKey ( key )
setupStr = " SetupP " + str ( player . pos )
setupMsg . setContents ( setupStr + " B " ) # enable buttons
setupMsg . send ( ID )
if player . rocksWon > = 1 :
setupMsg . setContents ( setupStr + " L0 " )
setupMsg . send ( ID )
if player . rocksWon > = 2 :
setupMsg . setContents ( setupStr + " L1 " )
setupMsg . send ( ID )
if player . papersWon > = 1 :
setupMsg . setContents ( setupStr + " L2 " )
setupMsg . send ( ID )
if player . papersWon > = 2 :
setupMsg . setContents ( setupStr + " L3 " )
setupMsg . send ( ID )
if player . scissorsWon > = 1 :
setupMsg . setContents ( setupStr + " L4 " )
setupMsg . send ( ID )
if player . scissorsWon > = 2 :
setupMsg . setContents ( setupStr + " L5 " )
setupMsg . send ( ID )
def ClientLeft ( self , ID ) :
position = - 1
for player in self . playerList [ : ] :
if player . ID == ID :
position = player . pos
self . playerList . remove ( player )
for player in self . agePlayers [ : ] :
if player [ 0 ] == ID :
self . agePlayers . remove ( player )
if position == - 1 : # client wasn't playing
return
print " ID: " + str ( self . ID ) + " Client ID# " + str ( ID ) + " has left, cleaning up after him "
if len ( self . playerList ) == 0 : # no players left to cleanup the position
if len ( self . agePlayers ) == 0 : # no players in age left to cleanup the table
self . queueCleanup . append ( position )
else :
cleanup = ptPythonMsg ( )
cleanup . setContents ( " Cleanup " + str ( position ) )
cleanup . setKey ( self . agePlayers [ 0 ] [ 1 ] )
cleanup . send ( self . agePlayers [ 0 ] [ 0 ] )
cleanup . setContents ( " ShowIdleAnimation " )
cleanup . send ( self . agePlayers [ 0 ] [ 0 ] )
for num in range ( len ( self . playerList ) ) : # let everyone know of their new player numbers
numberMsg = ptPythonMsg ( )
numberMsg . setKey ( self . playerList [ num ] . key )
numberMsg . setContents ( " Number " + str ( num + 1 ) )
numberMsg . send ( self . playerList [ num ] . ID )
if position != - 1 :
self . SendToAll ( " Drop " + str ( position ) )
def HandleAdd ( self , senderID , key , pos ) :
for player in self . playerList :
if player . pos == pos :
print " ID: " + str ( self . ID ) + " Ignoring client ID# " + str ( senderID ) + " request to play since someone is already sitting in their requested position: " + str ( pos )
return
print " ID: " + str ( self . ID ) + " Adding client ID# " + str ( senderID ) + " to player list. They are playing position " + str ( pos )
player = heekPlayer ( )
player . ID = senderID
player . key = key
player . pos = pos
self . playerList . append ( player )
reply = ptPythonMsg ( )
reply . setContents ( " Player " + str ( len ( self . playerList ) ) )
reply . setKey ( key )
reply . send ( senderID )
reply . setContents ( " GetPoints " )
reply . send ( senderID )
reply . setContents ( " GetName " )
reply . send ( senderID )
def HandleRemove ( self , senderID , key ) :
print " ID: " + str ( self . ID ) + " Removing client ID# " + str ( senderID ) + " from player list. "
for player in self . playerList :
if player . ID == senderID and player . key == key :
self . playerList . remove ( player )
if len ( self . playerList ) == 0 : # last player left
print " ID: " + str ( self . ID ) + " Last player is requesting a leave, telling him to clean up "
if self . countdownStarted :
player . SendMessage ( " StopCountdown " )
self . countdownStarted = 0
player . SendMessage ( " ShowIdleAnimation " )
if player . points != - 1 :
print " ID: " + str ( self . ID ) + " Giving last player the remaining points in the pot: " + str ( self . pot )
player . SendMessage ( " SetPoints " + str ( player . points + self . pot ) )
self . pot = 0
player . SendMessage ( " Goodbye " )
#self.ResetGame()
break
for num in range ( len ( self . playerList ) ) : # let everyone know of their new player numbers
numberMsg = ptPythonMsg ( )
numberMsg . setKey ( self . playerList [ num ] . key )
numberMsg . setContents ( " Number " + str ( num + 1 ) )
numberMsg . send ( self . playerList [ num ] . ID )
def HandleChoice ( self , senderID , key , choice ) :
print " ID: " + str ( self . ID ) + " Player # " + str ( senderID ) + " has chosen " + str ( choice )
for player in self . playerList :
if player . ID == senderID and player . key == key :
if player . points != - 1 and not player . isPlaying :
ante = self . CalculateAnte ( player . points )
player . points - = ante
self . pot + = ante
player . isPlaying = 1
player . SendMessage ( " SetPoints " + str ( player . points ) )
player . choice = choice
self . HandlePlayerReady ( )
def HandleCountdownFinished ( self ) :
print " ID: " + str ( self . ID ) + " Countdown has finished "
self . PlayGame ( )
def HandleChoiceAnimFinished ( self ) :
print " ID: " + str ( self . ID ) + " Choice animation has finished "
if not self . HandleGameWinner ( ) :
self . ResetRound ( )
self . SendToAll ( " ShowIdleAnimation " )
self . SendToAll ( " Enable " )
def HandleWinAnimFinished ( self ) :
self . SendToAll ( " ShowIdleAnimation " )
self . SendToAll ( " Enable " )
def HandleLinkIn ( self , senderID , key ) :
self . agePlayers . append ( ( senderID , key ) )
if len ( self . queueCleanup ) != 0 :
for item in self . queueCleanup :
cleanup = ptPythonMsg ( )
cleanup . setContents ( " Cleanup " + str ( item ) )
cleanup . setKey ( self . agePlayers [ 0 ] [ 1 ] )
cleanup . send ( self . agePlayers [ 0 ] [ 0 ] )
self . queueCleanup = [ ]
idle = ptPythonMsg ( )
idle . setContents ( " ShowIdleAnimation " )
idle . setKey ( self . agePlayers [ 0 ] [ 1 ] )
idle . send ( self . agePlayers [ 0 ] [ 0 ] )
self . SendTableState ( senderID , key )
def HandlePoints ( self , senderID , key , points ) :
print " ID: " + str ( self . ID ) + " Player ID# " + str ( senderID ) + " has " + str ( points ) + " points "
for player in self . playerList :
if player . ID == senderID and player . key == key :
player . points = points
if player . name != " " :
self . SendWelcomeMsg ( player . name , player . points )
def HandleName ( self , senderID , key , name ) :
for player in self . playerList :
if player . ID == senderID and player . key == key :
player . name = name
if player . points != - 1 :
self . SendWelcomeMsg ( player . name , player . points )
return
def onInit ( ) :
global heekTables
print " RestorationGuild.py is initializing "
heekTables = [ ]
def onShutdown ( ) :
print " RestorationGuild.py is shutting down "
#def onUpdate(secs):
#global curtime
#global lastupdate
#global heekPlayerList
#if lastupdate == 0:
#lastupdate = secs
#curtime = secs
#if curtime - lastupdate >= 1:
# put any code here that wants to be run every second (nothing currently)
#lastupdate += 1
def onClientLeft ( ID ) :
global heekTables
for table in heekTables :
table . ClientLeft ( ID )
def onMsgReceived ( msg ) :
global heekTables
msgContents = msg . getContents ( )
senderID = msg . getSenderID ( )
key = msg . getKey ( )
print " Message received from client. ID#: " + str ( msg . getSenderID ( ) ) + " Contents: " + msg . getContents ( )
if len ( msgContents ) > 3 and msgContents [ : 3 ] == " Add " : # they want to be added to our player list
options = msgContents [ 4 : ] . split ( ' ' )
pos = options [ 0 ]
tableID = options [ 1 ]
for table in heekTables :
if table . ID == tableID :
table . HandleAdd ( senderID , key , pos )
elif msgContents == " Remove " : # they want to be removed from our player list
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleRemove ( senderID , key )
elif msgContents == " Rock " :
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleChoice ( senderID , key , kRock )
elif msgContents == " Paper " :
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleChoice ( senderID , key , kPaper )
elif msgContents == " Scissors " :
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleChoice ( senderID , key , kScissors )
elif msgContents == " CountdownFinished " :
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleCountdownFinished ( )
elif msgContents == " ChoiceAnimFinished " :
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleChoiceAnimFinished ( )
elif msgContents == " GameWinAnimFinished " :
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleWinAnimFinished ( )
elif len ( msgContents ) > 6 and msgContents [ : 6 ] == " LinkIn " : # client telling us it's in the age
tableID = msgContents [ 7 : ]
for table in heekTables :
if table . ID == tableID :
table . HandleLinkIn ( senderID , key )
return
# must be a new table, add it to our list
print ( " Table ID # " + str ( tableID ) + " isn ' t in our list of games, adding it " )
newTable = heekGame ( )
newTable . ID = tableID
newTable . HandleLinkIn ( senderID , key )
heekTables . append ( newTable )
elif len ( msgContents ) > 6 and msgContents [ : 6 ] == " Points " :
points = int ( msgContents [ 7 : ] )
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandlePoints ( senderID , key , points )
elif len ( msgContents ) > 4 and msgContents [ : 4 ] == " Name " :
name = msgContents [ 5 : ]
for table in heekTables :
if table . PlayerIDInGame ( senderID ) :
table . HandleName ( senderID , key , name )
else :
print " Unknown message, not handling "