#ifdef STATIC import static "ecere" #else import "ecere" #endif import remote "ScrabbleServer" define TileSize = 32; enum SquareValue { normal, doubleLetter, dl = doubleLetter, tripleLetter, tl = tripleLetter, doubleWord, dw = doubleWord, tripleWord, tw = tripleWord }; enum Direction { horizontal, vertical }; define TrayHeight = 550; define TrayLeft = 50; define TrayWidth = 300; define ThrowHeight = 620; define BoardX = 20; define BoardY = 20; define MaxPlayers = 4; SquareValue squareValues[15][15] = { { tw, 0, 0,dl, 0, 0, 0,tw, 0, 0, 0,dl, 0, 0,tw }, { 0,tw, 0, 0, 0,tl, 0, 0, 0,tl, 0, 0, 0,tw, 0 }, { 0, 0,tw, 0, 0, 0,dl, 0,dl, 0, 0, 0,tw, 0, 0 }, { dl, 0, 0,tw, 0, 0, 0,dl, 0, 0, 0,tw, 0, 0,dl }, { 0, 0, 0, 0,tw, 0, 0, 0, 0, 0,tw, 0, 0, 0, 0 }, { 0,tl, 0, 0, 0,tl, 0, 0, 0,tl, 0, 0, 0,tl, 0 }, { 0, 0,dl, 0, 0, 0,dl, 0,dl, 0, 0, 0,dl, 0, 0 }, { tw, 0, 0,dl, 0, 0, 0,tw, 0, 0, 0,dl, 0, 0,tw }, { 0, 0,dl, 0, 0, 0,dl, 0,dl, 0, 0, 0,dl, 0, 0 }, { 0,tl, 0, 0, 0,tl, 0, 0, 0,tl, 0, 0, 0,tl, 0 }, { 0, 0, 0, 0,tw, 0, 0, 0, 0, 0,tw, 0, 0, 0, 0 }, { dl, 0, 0,tw, 0, 0, 0,dl, 0, 0, 0,tw, 0, 0,dl }, { 0, 0,tw, 0, 0, 0,dl, 0,dl, 0, 0, 0,tw, 0, 0 }, { 0,tw, 0, 0, 0,tl, 0, 0, 0,tl, 0, 0, 0,tw, 0 }, { tw, 0, 0,dl, 0, 0, 0,tw, 0, 0, 0,dl, 0, 0,tw } }; Color valueColors[SquareValue] = { 0, skyBlue, slateBlue, pink, red }; enum Letters { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z, blank, empty }; enum Languages { english, french }; // FRANCAIS int lettersCount[Languages][Letters] = { { 9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1, 2, 0 }, { 9, 2, 2, 3, 15, 2, 2, 2, 8, 1, 1, 5, 3, 6, 6, 2, 1, 6, 6, 6, 6, 2, 1, 1, 1, 1, 2, 0 } }; int lettersValue[Languages][Letters] = { { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3,10, 1, 1, 1, 1, 4, 4, 8, 4, 10, 0, 0 }, { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 10, 1, 2, 1, 1, 3, 8, 1, 1, 1, 1, 4, 10, 10, 10, 10, 0, 0 } }; Scrabble scrabble {}; class DefineBlank : Window { text = "Please choose the value of your blank tile"; size = { 250, 480 }; borderStyle = fixed; ListBox list { this; position = { 20, 20 }; size = { 80, 420 }; bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods) { if(list.currentRow) button.disabled = false; return true; } bool NotifyDoubleClick(ListBox listBox, int x, int y, Modifiers mods) { if(!button.disabled) button.NotifyClicked(this, button, 0,0,0); return true; } }; DataField field { class(Letters) }; Button button { this; text = "Choose"; size = { 80 }; isDefault = true; position = { 130, 420 }; disabled = true; bool NotifyClicked(Button button, int x, int y, Modifiers mods) { Destroy((DialogResult)(Letters)list.currentRow.GetData(field)); return true; } }; DefineBlank() { Letters c; list.AddField(field); for(c = 0; c BoardX && mx < BoardX + TileSize * 15 && my > BoardY && my < BoardY + TileSize * 15) { int x = (mx - BoardX) / TileSize; int y = (my - BoardY) / TileSize; if(boardLetters[y][x] != empty && lastBoard[y][x] == empty) { letters[numLetters] = boardLetters[y][x]; dragLetter = numLetters; boardLetters[y][x] = empty; blankValues[y][x] = empty; numLetters++; dragging = true; dragY = my; dragPos = -1; Capture(); out = true; moveX = x * TileSize + BoardX - TrayLeft; moveY = TrayHeight - BoardY - y * TileSize; startX = moveX; startY = moveY; lastX = moveX; dragX = mx; } } } // Picking letters in your hand for(c = 0; c < numLetters; c++) { int x1 = TrayLeft + positions[c]; int y1 = TrayHeight; if(mx >= x1 && my >= y1 && mx < x1 + TileSize && my < y1 + TileSize) { dragging = true; dragY = my; dragX = mx; moveY = 0; startY = 0; moveX = positions[c]; startX = positions[c]; lastX = positions[c]; dragLetter = c; dragPos = -1; out = false; Capture(); break; } } // Picking letters to throw if(my > ThrowHeight && mx >= TrayLeft && mx < TrayLeft + numThrowLetters * TileSize) { int c = (mx - TrayLeft) / TileSize; letters[numLetters] = throwLetters[c]; dragLetter = numLetters; memmove(throwLetters + c, throwLetters + c + 1, sizeof(int) * (numThrowLetters - c - 1)); numThrowLetters--; numLetters++; dragging = true; dragY = my; dragPos = -1; Capture(); out = true; moveX = c * TileSize; moveY = TrayHeight - ThrowHeight; startX = moveX; startY = moveY; lastX = moveX; dragX = mx; } return true; } int ::ComparePositions(int * a, int * b) { int posA = (*a == scrabble.dragLetter) ? scrabble.moveX : scrabble.positions[*a]; int posB = (*b == scrabble.dragLetter) ? scrabble.moveX : scrabble.positions[*b]; if(posA < posB) return -1; else if(posA > posB) return 1; else return 0; } bool OnMouseMove(int mx, int my, Modifiers mods) { if(dragging) { int x; int y; int ordered[7]; int c; bool collision = false; y = startY + dragY - my; x = startX + mx - dragX; moveX = x; if(y < 0 && y > -TileSize && moveX >= TrayLeft && moveX < TrayLeft + TrayWidth) y = 0; moveY = y; for(c = 0; c -TileSize && moveX + TileSize >= 0 && moveX <= TrayWidth) { qsort(ordered, numLetters, sizeof(int), ComparePositions); if(!out && dragPos != -1 && ordered[dragPos] != dragLetter) { int pos; int oldValue = ordered[dragPos]; for(c = 0; c= 0 && moveX <= TrayWidth) { for(c = 0; c moveX && positions[c] < moveX + TileSize) break; } } // COLLISION! (Insert in between?) if(out && c != numLetters) collision = true; } if(moveX >= lastX || collision) { int end; for(c = 0; c= 0; c--) { if(((ordered[c] == dragLetter) ? moveX : positions[ordered[c]]) + TileSize > end) { if(ordered[c] != dragLetter) positions[ordered[c]] = end - TileSize; else moveX = end - TileSize; } end = (ordered[c] == dragLetter) ? moveX : positions[ordered[c]]; } } if(moveX < lastX || collision) { int end; for(c = numLetters-1; c>=0; c--) { if(ordered[c] == dragLetter) { c--; break; } } end = moveX; for(; c >= 0; c--) { if(((ordered[c] == dragLetter) ? moveX : positions[ordered[c]]) + TileSize > end) { if(ordered[c] != dragLetter) positions[ordered[c]] = end - TileSize; else moveX = end - TileSize; } end = (ordered[c] == dragLetter) ? moveX : positions[ordered[c]]; } // LEFT LIMIT end = 0; for(c = 0; c= TileSize || moveY < -TileSize; lastX = moveX; for(c = 0; c BoardX && mx < BoardX + TileSize * 15 && my > BoardY && my < BoardY + TileSize * 15) { x = (mx - BoardX) / TileSize; y = (my - BoardY) / TileSize; if(boardLetters[y][x] == empty) { moveX = x * TileSize + BoardX - TrayLeft; moveY = TrayHeight - BoardY - y * TileSize; } } } Update(null); } return true; } void FixLetters() { int end; int ordered[7]; int c; for(c = 0; c= 0; c--) { if(positions[ordered[c]] + TileSize > end) positions[ordered[c]] = end - TileSize; end = positions[ordered[c]]; } } bool OnLeftButtonUp(int mx, int my, Modifiers mods) { if(dragging) { dragging = false; ReleaseCapture(); if(my > ThrowHeight) { throwLetters[numThrowLetters++] = letters[dragLetter]; memmove(letters + dragLetter, letters + dragLetter + 1, sizeof(int) * (numLetters - dragLetter - 1)); memmove(positions + dragLetter, positions + dragLetter + 1, sizeof(int) * (numLetters - dragLetter - 1)); numLetters--; dragLetter = -1; } // Dropping Letters on the board if(gameStarted && turn == playerID) { if(mx > BoardX && mx < BoardX + TileSize * 15 && my > BoardY && my < BoardY + TileSize * 15) { int x = (mx - BoardX) / TileSize; int y = (my - BoardY) / TileSize; if(boardLetters[y][x] == empty) { boardLetters[y][x] = letters[dragLetter]; memmove(letters + dragLetter, letters + dragLetter + 1, sizeof(int) * (numLetters - dragLetter - 1)); memmove(positions + dragLetter, positions + dragLetter + 1, sizeof(int) * (numLetters - dragLetter - 1)); numLetters--; dragLetter = -1; if(boardLetters[y][x] == blank) { DefineBlank dialog { master = this }; blankValues[y][x] = (Letters)dialog.Modal(); } } } } if(dragLetter != -1) { positions[dragLetter] = moveX; dragLetter = -1; FixLetters(); } Update(null); } return true; } DataField scoreFields[MaxPlayers]; Button playBtn { this, text = "Play", bevel = false, position = { 520, 540 }; font = { "Arial", 20, true }; opacity = 0; drawBehind = true; bool NotifyClicked(Button button, int x, int y, Modifiers mods) { if(!numThrowLetters && gameStarted && turn == playerID) { int x, y; PlayedMove move { }; for(y = 0; y<15; y++) { for(x = 0; x<15; x++) { if(lastBoard[y][x] == empty && boardLetters[y][x] != empty) { move.tiles[move.numTiles].x = x; move.tiles[move.numTiles].y = y; move.tiles[move.numTiles].letter = boardLetters[y][x]; move.tiles[move.numTiles].blankValue = blankValues[y][x]; move.numTiles++; } } } if(move.numTiles <= 7 && move.numTiles > 0) { if(server.PlayTiles(move)) { memcpy(lastBoard, boardLetters, sizeof(lastBoard)); AddLetters(move); Update(null); } } } return true; } }; void AddLetters(PlayedMove move) { int end = 0; int c; for(c = 0; c end) end = positions[c] + TileSize; for(c = 0; c