Commits

David Krauth committed 9a71282

Incremental update

Comments (0)

Files changed (7)

 ANNOTATE_END_TOKEN  = '}'
 TAG_TOKEN           = '['
 TAG_END_TOKEN       = ']'
-
+NAG_TOKEN           = '$'
 
 # def create_pgn(pgn):
 #     pgn['Site'] = 'http://www.dakrauth.com/chess'
         self.move = symbol
         self.is_white = is_white
         self.move_count = move_count
+        self.nag = None
 
 
 #===============================================================================
         self.next_ply.annotations.append(annotation)
         
     #---------------------------------------------------------------------------
+    def nag(self, data):
+        self.next_ply.nag = data
+        
+    #---------------------------------------------------------------------------
     def __iadd__(self, move):
         if self.is_white:
             self.move_count += 1
         return c.isalnum() or (c in '+-/*=#_:?!')
 
     #---------------------------------------------------------------------------
-    def read_symbol_tokens(chars):
+    def isdigit(c):
+        return c.isdigit()
+
+    #---------------------------------------------------------------------------
+    def read_tokens(chars, validator=is_valid_token):
         c = stream.read(1)
         while c and is_valid_token(c):
             chars += c
         
             #--- Process valid symbol tokens
             if is_valid_token(ch):
-                symbol = read_symbol_tokens(ch)
+                symbol = read_tokens(ch)
                 if not symbol.isdigit():
             
                     if symbol in Pgn.RESULT_STRINGS:
             #--- Discard rest of comment line
             elif ch == COMMENT_TOKEN:
                 stream.readline()
+                
+            elif ch == NAG_TOKEN:
+                nag = read_tokens(ch, isdigit)
             
             else:
                 raise PgnParseError('Invalid token "%s"' % ch, stream)
 
 #-------------------------------------------------------------------------------
 if __name__ == '__main__':
-    import sys
-    parser = pgn_parser(open(sys.argv[1]))
+    pgn = """
+[Event "ICC 5 0 u"]
+[Site "Internet Chess Club"]
+[Date "2004.01.25"]
+[Round "-"]
+[White "guest920"]
+[Black "IceBox"]
+[Result "0-1"]
+[ICCResult "White checkmated"]
+[BlackElo "1498"]
+[Opening "French defense"]
+[ECO "C00"]
+[NIC "FR.01"]
+[Time "04:44:56"]
+[TimeControl "300+0"]
+
+1. e4 e6 2. Nf3 d5 $2 3. exd5 (3. e5 g6 4. h4) exd5 4. Qe2+ Qe7 5. Qxe7+ Bxe7 6. d3 Nf6 7. Be3
+Bg4 8. Nbd2 c5 9. h3 Be6 10. O-O-O Nc6 11. g4 Bd6 12. g5 Nd7 13. Rg1 d4 14.
+g6 fxg6 15. Bg5 Rf8 16. a3 Bd5 17. Re1+ Nde5 18. Nxe5 Nxe5 19. Bf4 Rf5 20.
+Bxe5 Rxe5 21. Rg5 Rxe1# {Black wins} 0-1"""
+    
+    parser = pgn_parser(StringIO(pgn))
     for i, game in enumerate(parser):
         print 'Game %d %s' % (i + 1, '-' * 50)
         print game

media/css/chess2.css

 
 .box { background-color: #D2D7E3; }
 
-a { color: #3C465D;}
+a { color: #1840A3; }
 a:hover { text-decoration: underline; }
 thead th { background-color: #9BABC7; color: #fff; text-shadow: #000 0px 1px 1px; font-weight: normal; }
 tr.even td { background-color: #F1F5FA; }
         
 
 #===============================================================================
-class Game(models.Model):
+class _BaseGame(models.Model):
+    pgn = models.TextField(blank=True)
+    
+    #===========================================================================
+    class Meta:
+        abstract = True
+
+    #---------------------------------------------------------------------------
+    @property
+    def gamelog(self):
+        pgn = chesslib.Pgn.parse(self.pgn.encode('utf8'))
+        return chesslib.Game(pgn)
+
+
+
+#===============================================================================
+class Game(_BaseGame):
     
     #===========================================================================
     class Result(ChoiceEnumeration):
         default=Result.DEFAULT,
     )
     
-    pgn = models.TextField(blank=True)
     white = models.ForeignKey(ChessProfile, related_name='game_white_set')
     black = models.ForeignKey(ChessProfile, related_name='game_black_set')
 
     @property
     def is_complete(self):
         return self.result != self.Result.UNDECIDED
-        
-    #---------------------------------------------------------------------------
-    @property
-    def gamelog(self):
-        pgn = chesslib.Pgn.parse(self.pgn.encode('utf8'))
-        return chesslib.Game(pgn)
-        
+
+
 
 #===============================================================================
-class Opening(models.Model):
+class Opening(_BaseGame):
     eco = models.CharField(max_length=4)
     name = models.CharField(max_length=50)
     variation = models.CharField(max_length=50)
-    pgn = models.TextField(blank=True)
     fen = models.CharField(max_length=80)
 
     #---------------------------------------------------------------------------
     def __unicode__(self):
         return u'%s %s %s' % (self.eco, self.name, self.variation)
         
+    #---------------------------------------------------------------------------
+    @models.permalink
+    def get_absolute_url(self):
+        return ('chess-opening', [str(self.id)])
+        
 
 
 #===============================================================================

templates/echess/game.html

-{% extends "echess/base.html" %}
-{% block extra_head %}
-    <script type="text/javascript" language="javascript">
-        var fenMoveCount = 0;
-        var fenMoves = [ {% for f in gamelog.fen %}
-            FENObject("{{ f }}"),{% endfor %}
-        ];
-        
-        $(document).ready(function() { on_init("/media/chess/img/") });
-    </script>
-{% endblock extra_head %}
-{% block chess_content %}
-    <div class="span-10 colborder">
-        <div id="InfoHeader"></div>
-        <div id="board-wrapper">
-            <div id="rows">
-                <div>8</div>
-                <div>7</div>
-                <div>6</div>
-                <div>5</div>
-                <div>4</div>
-                <div>3</div>
-                <div>2</div>
-                <div>1</div>
-            </div>
-            <div id="board">
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-                <div class="black"></div>
-                <div class="white"></div>
-            </div>
-            <div id="cols">
-                <div>a</div>
-                <div>b</div>
-                <div>c</div>
-                <div>d</div>
-                <div>e</div>
-                <div>f</div>
-                <div>g</div>
-                <div>h</div>
-            </div>
-
-            <br clear="all">
-            <div id="playback">
-                <img onclick="PlayMove(-1);" src="/media/chess/img/Back.png" alt="Back" onmouseup="SetImage(this, 'Back');" onmousedown="SetImage(this, 'Back2');" />
-                <img onclick="PlayMove(0);" src="/media/chess/img/Home.png" alt="Home" name="Home" onmouseup="SetImage(this, 'Home');" onmousedown="SetImage(this, 'Home2');" />
-                <img onclick="rotate_board();" src="/media/chess/img/Rotate.png" alt="Rotate" name="Rotate" onmouseup="SetImage(this, 'Rotate');" onmousedown="SetImage(this, 'Rotate2');" />
-                <img onclick="PlayMove(null);" src="/media/chess/img/End.png" alt="End" name="End" onmouseup="SetImage(this, 'End');" onmousedown="SetImage(this, 'End2');" />
-                <img onclick="PlayMove(1);" src="/media/chess/img/Next.png" alt="Next" name="Next" onmouseup="SetImage(this, 'Next');" onmousedown="SetImage(this, 'Next2');" />
-            </div>
-            
-            {% if not game.is_complete %}
-            <fieldset>
-                <legend>Next Move</legend>
-                <p>
-                    Input a move by first clicking the piece, then by clicking the destination square.
-                    Alternatively, use
-                    <a href="/media/chess/img/PGN_Standard.html">
-                        <em>standard algebraic notion</em>
-                    </a>
-                     (i.e.: Nf3) or enter source and destination squares of the move (i.e.: g1f3).
-                </p>
-                <form action="" id="move_form" method="post">
-                    <p>
-                        <input type="hidden" name="Action" value="MatchMove" />
-                        Move: 
-                        <input type="text" size="8" id="next-move" name="Move" />
-                        <input type="hidden" name="Id" value="2" />
-                        <br />
-                        <input type="checkbox" name="Draw" value="Draw?" />
-                        Offer draw?
-                    </p>
-                    <hr />
-                    <p>
-                        <input type="submit" name="_resign" value="Resign" />
-                        <input type="submit" name="_move" value="Submit" /> 
-                    </p>
-                </form>
-            </fieldset>
-            {% endif %}
-        </div>
-
-    </div>
-    <div class="span-6 last">
-        <h4 class="caps">Game History</h4>
-        <div class="box">
-            <div id="GameInfo">
-                <img src="/media/chess/img/wplayer.gif" alt="wplayer" />
-                {{ gamelog.pgn.white }} v.
-                <img src="/media/chess/img/bplayer.gif" alt="bplayer" />
-                {{ gamelog.pgn.black }}
-                <br />
-                <em>{{ gamelog.pgn.date }}</em>
-            </div>
-            <hr />
-            <div id="movetext"> {% for move in gamelog.moves %}
-                {% if move.is_white %}<strong>{{ move.counter }}</strong>{% endif %}
-                <span id="ply{{ move.index }}">{{ move.notation }}</span>
-                {% endfor %}
-                <em>{{ gamelog.pgn.result }}</em>
-            </div>
-        </div>
-    
-        <h4 class="caps">Captured Pieces</h4>
-        <div class="box">
-            <div id="CapturedPieces"></div>
-        </div>
-
-        <h4 class="caps">Analysis</h4>
-        <div class="box">
-            <div id="Analysis">
-                Switch to Analysis mode, where moves are not logged
-                <form action="chess.cgi" method="post" onsubmit="return get_move_text();" target="AnalysisWindow" name="Analyze">
-                    <input type="hidden" id="analysis_movetext" name="movetext" value="" />
-                    <input type="submit" value="Analyze" />
-                </form>
-            </div>
-        </div>
-    </div>
-{% endblock chess_content %}
-
-
+{% extends "echess/game_base.html" %}
+{% block move_content %}
+{% if game and not game.is_complete %}
+<fieldset>
+    <legend>Next Move</legend>
+    <p>
+        Input a move by first clicking the piece, then by clicking the destination square.
+        Alternatively, use
+        <a href="/media/chess/img/PGN_Standard.html">
+            <em>standard algebraic notion</em>
+        </a>
+         (i.e.: Nf3) or enter source and destination squares of the move (i.e.: g1f3).
+    </p>
+    <form action="" id="move_form" method="post">
+        <p>
+            <input type="hidden" name="Action" value="MatchMove" />
+            Move: 
+            <input type="text" size="8" id="next-move" name="Move" />
+            <input type="hidden" name="Id" value="2" />
+            <br />
+            <input type="checkbox" name="Draw" value="Draw?" />
+            Offer draw?
+        </p>
+        <hr />
+        <p>
+            <input type="submit" name="_resign" value="Resign" />
+            <input type="submit" name="_move" value="Submit" /> 
+        </p>
+    </form>
+</fieldset>
+{% endif %}
+{% endblock move_content %}

templates/echess/game_base.html

+{% extends "echess/base.html" %}
+{% block extra_head %}
+    <script type="text/javascript" language="javascript">
+        var fenMoveCount = 0;
+        var fenMoves = [ {% for f in gamelog.fen %}
+            FENObject("{{ f }}"),{% endfor %}
+        ];
+        
+        $(document).ready(function() { on_init("/media/chess/img/") });
+    </script>
+{% endblock extra_head %}
+{% block chess_content %}
+    <div class="span-10 colborder">
+        <div id="InfoHeader"></div>
+        <div id="board-wrapper">
+            <div id="rows">
+                <div>8</div>
+                <div>7</div>
+                <div>6</div>
+                <div>5</div>
+                <div>4</div>
+                <div>3</div>
+                <div>2</div>
+                <div>1</div>
+            </div>
+            <div id="board">
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+                <div class="black"></div>
+                <div class="white"></div>
+            </div>
+            <div id="cols">
+                <div>a</div>
+                <div>b</div>
+                <div>c</div>
+                <div>d</div>
+                <div>e</div>
+                <div>f</div>
+                <div>g</div>
+                <div>h</div>
+            </div>
+
+            <br clear="all">
+            <div id="playback">
+                <img onclick="PlayMove(-1);" src="/media/chess/img/Back.png" alt="Back" onmouseup="SetImage(this, 'Back');" onmousedown="SetImage(this, 'Back2');" />
+                <img onclick="PlayMove(0);" src="/media/chess/img/Home.png" alt="Home" name="Home" onmouseup="SetImage(this, 'Home');" onmousedown="SetImage(this, 'Home2');" />
+                <img onclick="rotate_board();" src="/media/chess/img/Rotate.png" alt="Rotate" name="Rotate" onmouseup="SetImage(this, 'Rotate');" onmousedown="SetImage(this, 'Rotate2');" />
+                <img onclick="PlayMove(null);" src="/media/chess/img/End.png" alt="End" name="End" onmouseup="SetImage(this, 'End');" onmousedown="SetImage(this, 'End2');" />
+                <img onclick="PlayMove(1);" src="/media/chess/img/Next.png" alt="Next" name="Next" onmouseup="SetImage(this, 'Next');" onmousedown="SetImage(this, 'Next2');" />
+            </div>
+            
+            {% block move_content %}{% endblock move_content %}
+        </div>
+
+    </div>
+    <div class="span-6 last">
+        <h4 class="caps">Game History</h4>
+        <div class="box">
+            <div id="GameInfo">
+                <img src="/media/chess/img/wplayer.gif" alt="wplayer" />
+                {{ gamelog.pgn.white|default:"?" }} v.
+                <img src="/media/chess/img/bplayer.gif" alt="bplayer" />
+                {{ gamelog.pgn.black|default:"?" }}
+                <br />
+                <em>{{ gamelog.pgn.date }}</em>
+            </div>
+            <hr />
+            <div id="movetext"> {% for move in gamelog.moves %}
+                {% if move.is_white %}<strong>{{ move.counter }}</strong>{% endif %}
+                <span id="ply{{ move.index }}">{{ move.notation }}</span>
+                {% endfor %}
+                <em>{{ gamelog.pgn.result }}</em>
+            </div>
+        </div>
+    
+        <h4 class="caps">Captured Pieces</h4>
+        <div class="box">
+            <div id="CapturedPieces"></div>
+        </div>
+
+        <h4 class="caps">Analysis</h4>
+        <div class="box">
+            <div id="Analysis">
+                Switch to Analysis mode, where moves are not logged
+                <form action="chess.cgi" method="post" onsubmit="return get_move_text();" target="AnalysisWindow" name="Analyze">
+                    <input type="hidden" id="analysis_movetext" name="movetext" value="" />
+                    <input type="submit" value="Analyze" />
+                </form>
+            </div>
+        </div>
+    </div>
+{% endblock chess_content %}
+
+

templates/echess/openings.html

         <tbody> {% for o in openings %}
             <tr class="{% cycle 'odd' 'even' %}">
                 <td><a href="{% url chess-eco-openings o.eco %}">{{ o.eco }}</a></td>
-                <td>{{ o.name }}</td>
-                <td><a href="{% url chess-opening o.id %}">{{ o.variation }}</a></td>
+                <td><a href="{% url chess-opening o.id %}">{{ o.name }}</a></td>
+                <td>{{ o.variation }}</td>
             </tr> {% endfor %}
         </tbody>
     </table>
 
 
 #-------------------------------------------------------------------------------
+def opening(request, pk):
+    o = get_object_or_404(Opening, pk=pk)
+    gamelog = o.gamelog
+    gamelog.play()
+    
+    return request_to_response(
+        request,
+        'echess/game.html', 
+        dict(gamelog=gamelog, opening=opening)
+    )
+
+
+#-------------------------------------------------------------------------------
 def games(request):
     games = Game.objects.all()
     return request_to_response(request, 'echess/game.html', dict(games=games))
 
 
 #-------------------------------------------------------------------------------
-def opening(request, pk):
-    o = get_object_or_404(Opening, pk=pk)
-    pgn = chesslib.Pgn.parse(o.pgn.encode('utf8'))
-    
-    moves = []
-    game = chesslib.Game(pgn)
-    game.play(moves.append)
-    
-    return request_to_response(
-        request,
-        'echess/game.html', 
-        dict(moves=moves, game=game, opening=o)
-    )
-
-
-#-------------------------------------------------------------------------------
 @login_required
 def new_game(request):
     if request.method == 'POST':
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.