5 // FOR COMMUNICATION //////////////////////////////////////////
12 void OnSerialize(SerialBuffer buffer)
16 buffer.Serialize(letter);
17 buffer.Serialize(blankValue);
20 void OnUnserialize(SerialBuffer buffer)
22 buffer.Unserialize(x);
23 buffer.Unserialize(y);
24 buffer.Unserialize(letter);
25 buffer.Unserialize(blankValue);
36 void OnSerialize(SerialBuffer buffer)
39 buffer.Serialize(numTiles);
41 buffer.Serialize(tiles[c]);
42 buffer.Serialize(player);
43 buffer.Serialize(score);
46 void OnUnserialize(SerialBuffer buffer)
49 buffer.Unserialize(numTiles);
51 buffer.Unserialize(tiles[c]);
52 buffer.Unserialize(player);
53 buffer.Unserialize(score);
62 void OnSerialize(SerialBuffer buffer)
64 buffer.Serialize(language);
65 buffer.Serialize((StaticString)players[0]);
66 buffer.Serialize((StaticString)players[1]);
67 buffer.Serialize((StaticString)players[2]);
68 buffer.Serialize((StaticString)players[3]);
71 void OnUnserialize(SerialBuffer buffer)
73 buffer.Unserialize(language);
74 buffer.Unserialize((StaticString)players[0]);
75 buffer.Unserialize((StaticString)players[1]);
76 buffer.Unserialize((StaticString)players[2]);
77 buffer.Unserialize((StaticString)players[3]);
81 //////////////////////////////////////////
91 ServerConnection connection;
99 static char * dicos[Languages] = { ":english.txt", ":dico.txt" };
103 int lettersAvailable[Letters];
104 int numLettersAvailable;
105 AVLTree<String> dictionary { };
107 Player players[MaxPlayers];
110 property Languages language
115 LoadWords(dicos[value]);
119 Letters board[15][15];
120 Letters blankValues[15][15];
128 for(c = 0; c<MaxPlayers; c++)
137 void GetTiles(int tilesPlayer, PlayedMove move)
139 Player player = players[tilesPlayer];
143 while(player.numLetters < 7 && numLettersAvailable)
146 int r = (Letters)GetRandom(0, numLettersAvailable-1);
149 for(letter = 0; letter<Letters::empty; letter++)
151 a += lettersAvailable[letter];
155 numLettersAvailable--;
156 lettersAvailable[letter]--;
158 player.letters[player.numLetters] = letter;
161 move.tiles[move.numTiles++].letter = letter;
170 for(c = 0; c<MaxPlayers; c++)
179 PlayedMove tiles { };
181 numLettersAvailable = 0;
183 for(l = 0; l<Letters::empty; l++)
185 numLettersAvailable += lettersCount[language][l];
186 lettersAvailable[l] = lettersCount[language][l];
189 seed = (uint)(GetTime() * 1000);
192 //Logf("Seeded with %d\n", seed);
194 for(y = 0; y<15; y++)
195 for(x = 0; x<15; x++)
196 board[y][x] = blankValues[y][x] = empty;
199 for(c = 0; c<MaxPlayers; c++)
208 strcpy(list.players[0], scrabbleGame.players[0] ? scrabbleGame.players[0].name : "");
209 strcpy(list.players[1], scrabbleGame.players[1] ? scrabbleGame.players[1].name : "");
210 strcpy(list.players[2], scrabbleGame.players[2] ? scrabbleGame.players[2].name : "");
211 strcpy(list.players[3], scrabbleGame.players[3] ? scrabbleGame.players[3].name : "");
212 list.language = scrabbleGame.language;
214 for(c = 0; c<MaxPlayers; c++)
217 scrabbleGame.GetTiles(c, tiles);
218 scrabbleGame.players[c].connection.GameStarted(list, tiles);
223 void LoadWords(char * fileName)
225 File f = FileOpen(fileName, read);
232 f.GetLine(word, sizeof(word));
233 dictionary.Add(CopyString(word));
239 IteratorPointer test1, test2;
240 test1 = dictionary.Find("gewurztraminer");
241 test2 = dictionary.Find("gewurstraminer");
247 bool CheckWord(Letters newBoard[15][15], Direction direction, int where, int start, int end, int * score)
253 int wordMultiplier = 1;
255 for(c = start; c<= end; c++)
257 int y = direction ? c : where;
258 int x = direction ? where : c;
259 Letters letter = newBoard[y][x];
262 if(board[y][x] == empty)
264 if(squareValues[y][x] == doubleLetter) multiplier = 2;
265 else if(squareValues[y][x] == tripleLetter) multiplier = 3;
268 wordScore += lettersValue[language][letter] * multiplier;
270 if(board[y][x] == empty)
272 if(squareValues[y][x] == doubleWord) wordMultiplier *= 2;
273 else if(squareValues[y][x] == tripleWord) wordMultiplier *= 3;
277 letter = blankValues[y][x];
278 word[len++] = (char)letter + 'a';
281 found = dictionary.Find(word) != null;
282 Logf("%s: %s\n", word, found ? "found :)" : "not found :(");
284 *score += wordScore * wordMultiplier;
288 bool VerifyMove(Letters newBoard[15][15], int * score)
293 Direction direction = horizontal;
297 int firstX = MAXINT, lastX = MININT;
298 int firstY = MAXINT, lastY = MININT;
299 int first, last, where;
300 int wordStart, wordEnd;
301 bool anchored = false;
305 for(y = 0; y<15; y++)
307 for(x = 0; x<15; x++)
309 if(board[y][x] == empty && newBoard[y][x] != empty)
313 if(x < firstX) firstX = x;
314 if(y < firstY) firstY = y;
315 if(x > lastX) lastX = x;
316 if(y > lastY) lastY = y;
321 if(!numLetters) return false;
322 if(lastY - firstY > 0)
324 if(lastX - firstX > 1) return false;
325 direction = vertical;
327 else if(lastX - firstX == 0)
329 if(((firstY > 0 && newBoard[firstY-1][firstX] != empty) ||
330 (firstY < 14 && newBoard[firstY+1][firstX] != empty)) &&
331 ((firstX == 0 || newBoard[firstY][firstX-1] == empty) &&
332 (firstX == 14 || newBoard[firstY][firstX+1] == empty)))
333 direction = vertical;
336 first = direction ? firstY : firstX;
337 last = direction ? lastY : lastX;
339 where = direction ? firstX : firstY;
341 for(c = first; c <= last; c++)
343 Letters letter = direction ? newBoard[c][where] : newBoard[where][c];
344 if(letter == empty) return false;
347 for(c = first; c>=0; c--)
349 Letters letter = direction ? newBoard[c][where] : newBoard[where][c];
350 if(letter == empty) break;
355 for(c = last; c<15; c++)
357 Letters letter = direction ? newBoard[c][where] : newBoard[where][c];
358 if(letter == empty) break;
363 if(!CheckWord(newBoard, direction, where, wordStart, wordEnd, score))
366 for(c = first; c <= last; c++)
368 if((direction ? board[c][where] : board[where][c]) == empty)
370 int wordStart, wordEnd;
373 for(a = where; a>=0; a--)
375 Letters letter = direction ? newBoard[c][a] : newBoard[a][c];
376 if(letter == empty) break;
381 for(a = where; a<15; a++)
383 Letters letter = direction ? newBoard[c][a] : newBoard[a][c];
384 if(letter == empty) break;
389 if(wordEnd > wordStart)
390 if(!CheckWord(newBoard, !direction, c, wordStart, wordEnd, score))
396 if(newBoard[7][7] != empty && board[7][7] == empty) anchored = true;
397 if(!anchored) return false;
398 if(numLetters == 7) *score += 50;
407 for(c = 0; c<MaxPlayers; c++)
409 delete scrabbleGame.players[c];
416 ScrabbleGame scrabbleGame;
418 remote class ServerConnection
428 //scrabbleGame.players[player.id] = null;
429 delete scrabbleGame.players[player.id];
431 scrabbleGame.EndGame();
438 if(!scrabbleGame.gameStarted)
441 for(c = 0; c<MaxPlayers; c++)
443 if(!scrabbleGame.players[c])
448 player = scrabbleGame.players[c] = Player { id = c };
449 player.connection = this;
451 incref scrabbleGame.players[c];
458 bool SetName(const String name)
462 player.name = CopyString(name);
463 if(!scrabble.scoreFields[player.id])
465 scrabble.scoreFields[player.id] = DataField { dataType = class(int), header = name, width = 40 };
466 //incref scrabble.scoreFields[player.id];
467 scrabble.scores.AddField(scrabble.scoreFields[player.id]);
469 scrabble.scoreFields[player.id].header = name;
474 bool PlayTiles(PlayedMove move)
476 if(player && scrabbleGame.players[scrabbleGame.curPlayer] == player)
478 Letters newBoard[15][15];
482 memcpy(newBoard, scrabbleGame.board, 15*15*sizeof(Letters));
483 for(c = 0; c<move.numTiles; c++)
485 if(newBoard[move.tiles[c].y][move.tiles[c].x] == empty)
487 newBoard[move.tiles[c].y][move.tiles[c].x] = move.tiles[c].letter;
488 scrabbleGame.blankValues[move.tiles[c].y][move.tiles[c].x] = move.tiles[c].blankValue;
493 if(scrabbleGame.VerifyMove(newBoard, &score))
495 for(c = 0; c<move.numTiles; c++)
499 for(d = 0; d<player.numLetters; d++)
500 if(player.letters[d] == move.tiles[c].letter)
502 memmove(player.letters + d, player.letters + d + 1, sizeof(int) * (player.numLetters - d - 1));
509 Logf("Letter not found!\n");
514 player.totalScore += score;
515 memcpy(scrabbleGame.board, newBoard, 15*15*sizeof(Letters));
517 scrabbleGame.curMove = move;
518 scrabbleGame.curMove.player = scrabbleGame.curPlayer;
519 scrabbleGame.curMove.score = score;
522 scrabbleGame.GetTiles(scrabbleGame.curPlayer, move);
524 for(c = 0; c<MaxPlayers; c++)
525 if(scrabbleGame.players[c])
526 scrabbleGame.players[c].connection.MovePlayed(scrabbleGame.curMove);
528 do { if(++scrabbleGame.curPlayer == MaxPlayers) scrabbleGame.curPlayer = 0; } while(!scrabbleGame.players[scrabbleGame.curPlayer]);
535 bool DiscardTiles(PlayedMove move)
537 if(player && scrabbleGame.numLettersAvailable >= move.numTiles && scrabbleGame.players[scrabbleGame.curPlayer] == player)
540 PlayedMove newTiles { };
542 for(c = 0; c<move.numTiles; c++)
545 for(d = 0; d<player.numLetters; d++)
546 if(player.letters[d] == move.tiles[c].letter)
548 memmove(player.letters + d, player.letters + d + 1, sizeof(int) * (player.numLetters - d - 1));
554 scrabbleGame.GetTiles(scrabbleGame.curPlayer, newTiles);
556 for(c = 0; c<move.numTiles; c++)
558 scrabbleGame.lettersAvailable[move.tiles[c].letter]++;
559 scrabbleGame.numLettersAvailable++;
562 scrabbleGame.curMove = { }; // TODO: Add informing other players of number of exchanged letters when passing...
563 scrabbleGame.curMove.player = scrabbleGame.curPlayer;
567 for(c = 0; c<MaxPlayers; c++)
568 if(scrabbleGame.players[c])
569 scrabbleGame.players[c].connection.MovePlayed(scrabbleGame.curMove);
571 do { if(++scrabbleGame.curPlayer == MaxPlayers) scrabbleGame.curPlayer = 0; } while(!scrabbleGame.players[scrabbleGame.curPlayer]);
578 virtual void MovePlayed(PlayedMove move);
579 virtual void GameStarted(PlayerList list, PlayedMove tiles);