Parcourir la source

code outline. not yet functional

George C. Privon il y a 8 ans
Parent
commit
95b941d5b5
2 fichiers modifiés avec 220 ajouts et 0 suppressions
  1. 35 0
      CarcassonneScore.py
  2. 185 0
      cgame.py

+ 35 - 0
CarcassonneScore.py

@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+"""
+Carcassonne score keeping system.
+"""
+
+import argparse
+import cgame
+
+def getargs():
+    """
+    Get command line arguments.
+    """
+
+    parser = argparse.ArgumentParser(description="Carcassonne score keeping \
+system.")
+    
+    return parser.parse_args()
+
+
+def main():
+    """
+    Main routine
+    """
+
+    args = getargs()
+
+    mygame = cgame.cgame()
+
+    mygame.runGame()
+
+    sys.stdout.write("Thanks for playing!\n\n")
+
+
+if __name__ == "__main__":
+    main()

+ 185 - 0
cgame.py

@@ -0,0 +1,185 @@
+#!/usr/bin/env python
+"""
+Carcassonne score keeping system.
+"""
+
+import re as _re
+import sys as _sys
+from datetime import datetime as _datetime
+import numpy as _np
+
+
+class cgame:
+    """
+    Carcassonne game object
+    """
+
+    def __init__(self):
+        """
+        Initialize some variables and set up a game
+        """
+
+        self.commands = [('n', 'next round'),
+                         ('r', 'record score and advance turn'),
+                         ('t', 'advance turn, no score'),
+                         ('b', 'additional turn for a player due to a builder'),
+                         ('e', 'end game (or play if already in postgame scoring'),
+                         ('s', '(current) score and game status'),
+                         ('?', 'print help')]
+        setupGame()
+
+
+    def showCommands(self):
+        """
+        Print out a list of valid commands for in-game play.
+        """
+
+        _sys.stderr.write('Possible commands:\n')
+        for entry in self.commands:
+            _sys.stderr.write('\t' + entry[0] + ': ' + entry[1] + '\n')
+
+
+    def setupGame(self):
+        """
+        Initialize a game
+        """
+
+        # check to see if there's a game which has not yet been finished (i.e., has a starttime but no endtime). If there is, resume it. Otherwise:
+        # generate a new game ID and enter a start time
+        # get a list of players (from database list)
+        # have user input which expansions are being used
+        time = _datetime.utcnow().strftime("%Y-%m-%dT%H:%M")
+
+        # insert this into the database
+
+        # general information
+        self.gameID =
+        # array of tuples with playerID and name from DB
+        self.players =
+        self.expansionIDs =
+
+        # game state information
+        self.state = 0  # 0 for main game, 1 for postgame, 2 for ended game
+        self.ntile = 1  # number of tiles played
+        self.nbuilder = 0   # number of tiles placed due to builders
+
+
+    def recordScore(gameID, playerIDs, expansionIDs, cround, state):
+        """
+        Record a score event in the game
+        """
+
+        if state:
+            ingame = 0
+
+        pname = getPlayerNames(playerIDs)
+
+
+       # for i, pname in enumerate(pname):
+
+        pID = input("")
+
+        # if the builder was used
+        BUILDERUSED = True
+
+        advanceTurn(cmdtime, gameID, playerID, nturn, builder=BUILDERUSED)
+
+        return 0
+
+
+    def advanceTurn(self, builder=False):
+        """
+        Make a new entry in the turns table
+        """
+
+        command = '''INSERT INTO turns VALUES ({0:d}, {1:d}, '''.format(self.gameID, self.nturn)
+        command = command + cmdtime
+        if builder:
+            bID = 1
+        else:
+            bID = 0
+
+        # compute playerID based on the turn number minus nbuilders / number of players
+        playerID = playerIDs[(nturns - nbuilder) / lnen(playerIDs)]
+        command = command + ', {0:d}, {1:d})'.format(bID, playerID)
+
+        c.execute(command)
+
+        self.nturn += 1
+        if builder:
+            self.nbuilder += 1
+
+
+    def runGame(self):
+        """
+        Main routine for entering games
+        """
+
+        # here wait for input for scores, advancing to next round, or completion of game
+
+        # for each step of entry, present a series of options, based on the list
+        # of playerIDs and expansions
+
+        while self.state < 2:
+            # set up prompt based on current round
+            if self.state:
+                prompt = "postgame > "
+            else:
+                prompt = "round: {0:d}, turn: {1:d} > ".format(1 + _np.floor((self.nturn-self.nbuilder) / len(self.playerIDs)),
+                                                               self.nturn-self.nbuilder)
+
+            try:
+                text = input(prompt)
+            except (EOFError, KeyboardInterrupt):
+                _sys.stderr.write('Improper input. Please retry\n')
+                showCommands()
+
+            if _re.match('e', cmd, _re.IGNORECASE):
+                advanceState()
+            elif _re.match('s', cmd, _re.IGNORECASE):
+                printStatus(tilestats=True)
+            elif _re.match('n', cmd, _re.IGNORECASE):
+                advanceTurn()
+            elif _re.match('r', cmd, _re.IGNORECASE):
+                recordScore()
+            elif _re.match('t', cmd, _re.IGNORECASE):
+                advanceTurn(builder=False)
+            elif _re.match('b', cmd, _re.IGNORECASE):
+                advanceTurn(builder=True)
+            elif _re.match('?'. cmd, _re.IGNORECASE):
+                showCommands()
+            else:
+                _sys.stderr.write('Command not understood. Please try again.\n')
+                showCommands()
+
+        if state == 2:
+            #game is over. write end time to the games table
+            time = _datetime.utcnow().strftime("%Y-%m-%dT%H:%M")
+            c.execute('''UPDATE games SET endtime = "''' + time + '''" WHERE gameID = ''' + str(gameID))
+            conn.commit()
+
+        printStatus(tilestats=False)
+
+        #### Is there a way to capture "ineffective" uses? For example,
+        #### meeples that don't score points because they end up in a meadow that's
+        #### controled by someone else?
+
+        return 0
+
+
+    def printStatus(self, tilestats=False):
+        """
+        Print the total score (current or final) for the specified gameID
+        """
+
+        for playerID in self.playerIDs:
+            pname = c.execute('SELECT name FROM players WHERE playerID={0:d}'.format(playerID[0])).fetchall()[0]
+            a = c.execute('SELECT points FROM scores WHER gameID={0:d} and playerID={1:d}'.format(self.gameID, playerID[0]))
+            res = a.fetchall()
+            score = _np.sum(res)
+
+            print(pname + ': {0:d}'.format(score))
+
+        print("{0:d} tiles played out of {1:d} total ({2:d} remaining).".format(self.ntiles,
+                                                                                self.totaltiles,
+                                                                                self.totaltiles - self.ntiles)