1 /*
  2 * Copyright (c) 2014-2015 Nonki Takahashi. All rights reserved.
  3 *
  4 * History:
  5 *  0.3 2015-10-26 Bug fixed of origin in toSGF and date in genSGFname, toSGF.
  6 *  0.2 2014-03-28 Bug fixed in Entry and toSGF.
  7 *  0.1 2014-01-28 Created. Ported from GoSimulator03.smallbasic .
  8 */
  9 
 10 /**
 11  * @fileOverview Rec - Game Record Object
 12  * @version 0.3
 13  * @author Nonki Takahashi
 14  */
 15 
 16 /**
 17  * Record Entry
 18  * @example
 19  * var e1 = new Entry(3, 4, BLACK);             // col = 3, row = 4, turn = BLACK
 20  * var e2 = new Entry(PASS, BLACK);             // means pass for BLACK
 21  * var e3 = new Entry(new Move(1, 2), WHITE);   // col = 1, row = 2, turn = WHITE
 22  * @class Represents Game Record Entry
 23  * @this {Entry}
 24  * @property {Number} x column co-ordinate of move (1 origin)
 25  * @property {Number} y row co-ordinate of move (1 origin)
 26  * @property {Number} turn turn BLACK or WHITE
 27  * @since 0.1
 28  */
 29 Entry = function() {
 30     if (arguments.length == 3) {
 31         this.mv = new Move(arguments[0], arguments[1]);
 32         this.turn = arguments[2];
 33     } else if (arguments.length == 2) {
 34         if (arguments[0] == PASS) {
 35             this.mv = new Move(PASS);
 36             this.turn = arguments[1];
 37         } else if (arguments[0] instanceof Object) {
 38             this.mv = arguments[0];
 39             this.turn = arguments[1];
 40         }
 41     }
 42 };
 43 
 44 /**
 45  * Game Record Object
 46  * @example
 47  * var rec1 = new Rec(sgfString);   // src = sgfString
 48  * var rec2 = new Rec(19);          // ro = 19
 49  * @class Represents Game Record Object
 50  * @this {Rec}
 51  * @property {Number} ro number of lines on board
 52  * @property {String[]} players names of players
 53  * @property {Number} numMove number of moves
 54  * @property {Entry[]} record game record
 55  * @property {String} score score string of the game
 56  * @property {Number} ptr pointer for replay
 57  * @since 0.1
 58  */
 59 Rec = function() {
 60     if ( typeof arguments[0] == "number") {
 61         this.ro = arguments[0];
 62         this.players = ["CPU", "CPU"];
 63         this.numMove = 0;
 64         this.score = "0";
 65         this.record = [];
 66         this.ptr = 0;
 67         this.from = BLACK;
 68         this.turn = BLACK;
 69         this.date = new Date();
 70     } else if ( typeof arguments[0] == "string") {
 71         this.players = [];
 72 		this.record = [];
 73         var parser = new SGFParser(arguments[0], this);
 74         parser.Collection();
 75     }
 76 };
 77 
 78 Rec.prototype = {
 79 
 80     /**
 81      * Generate SGF File Name
 82      * @return {String} SGF file name
 83      * @since 0.1
 84      */
 85     genSGFname : function() {
 86         var d = this.date;
 87         var fname = d.getFullYear().toString();
 88         if ((d.getMonth() + 1).toString().length == 1)
 89             fname += "0";
 90         fname += (d.getMonth() + 1).toString();
 91         if (d.getDate().toString().length == 1)
 92             fname += "0";
 93         fname += d.getDate().toString();
 94         fname += "_";
 95         if (d.getHours().toString().length == 1)
 96             fname += "0";
 97         fname += d.getHours().toString();
 98         if (d.getMinutes().toString().length == 1)
 99             fname += "0";
100         fname += d.getMinutes().toString();
101         if (d.getSeconds().toString().length == 1)
102             fname += "0";
103         fname += d.getSeconds().toString();
104         fname += "_";
105         fname += this.ro.toString();
106         fname += this.players[P_BLACK].charAt(0);
107         fname += this.players[P_WHITE].charAt(0);
108         fname += this.numMove;
109         if (this.score == "0")
110             fname += "D";
111         else {
112             fname += this.score.charAt(0);
113             fname += this.score.substr(2);
114         }
115         fname += ".sgf";
116         return fname;
117     },
118 
119     /**
120      * Rewind
121      * @since 0.1
122      */
123     rewind : function() {
124         this.ptr = 0;
125         this.turn = this.from;
126     },
127 
128     /**
129      * Replay - get next move from record
130      * @return {Move} next move
131      * @since 0.1
132      */
133     replay : function() {
134         return this.record[this.ptr++].mv;
135     },
136 
137     /**
138      * End of data
139      * @return {Boolean} true if end of data
140      * @since 0.1
141      */
142     eod : function() {
143         return (this.record.length <= this.ptr);
144     },
145 
146     /**
147      * Add a move to record
148      * @example
149      * move(col, row);
150      * move(PASS);
151      * move(new Move(col, row));
152      * @since 0.1
153      */
154     move : function() {
155         var entry;
156         if (arguments.length == 2)
157             entry = new Entry(arguments[0], arguments[1], this.turn);
158         else
159             entry = new Entry(arguments[0], this.turn);
160         var numRec = this.record.length;
161         this.record[numRec] = entry;
162         this.turn = OPPOSITE - this.turn; 
163     },
164 
165     /**
166      * Convert to SGF
167      * @return {String} SGF string
168      * @since 0.1
169      */
170     toSGF : function() {
171         // game of Go, format version, size of board
172         var buf = "(;GM[1]FF[4]SZ[" + this.ro + "]";
173         // player name
174         buf += "PB[" + this.players[P_BLACK] + "]PW[" + this.players[P_WHITE] + "]";
175         // score
176         buf += "RE[" + this.score + "]\n";
177         buf += "DT[";
178         var d = this.date;
179         buf += d.getFullYear().toString() + "-";
180         if ((d.getMonth() + 1).toString().length == 1)
181             buf += "0";
182         buf += (d.getMonth() + 1).toString() + "-";
183         if (d.getDate().toString().length == 1)
184             buf += "0";
185         buf += d.getDate().toString();
186         buf += "]KM[0.0]RU[Chinese]\n";
187         buf += "AP[" + programName + ":" + programVer + "]CA[UTF-8]\n";
188         for (var i = 0; i < this.record.length; i++) {
189             var turn = this.record[i].turn;
190             if (turn == BLACK)
191                 buf += ";B[";
192             else if (turn == WHITE)
193                 buf += ";W[";
194             if (!this.record[i].mv.isPass) {
195                 var col = this.record[i].mv.col;
196                 var row = this.record[i].mv.row;
197                 buf += ALPHA.charAt(col - 1) + ALPHA.charAt(row - 1);
198             }
199             buf += "]";
200             if (i % 10 == 9) {
201                 buf += "\n";
202             }
203         }
204         buf += ")\n";
205         return buf;
206     }
207 };
208