Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

obsolete ClientGameplayEvent string tiles in the backend #1164

Merged
merged 3 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions api/proto/ipc/omgwords.proto
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,9 @@ message ClientGameplayEvent {
string position_coords = 3;
// tiles that are being played (or exchanged). The `.` character is used
// for thru, and lowercase characters are used for blanks.
string tiles = 4;
// full_rack is the rack that the play is being made from. Note that the
// server already knows the full rack, so this does not need to be provided,
// unless our game is a broadcast/"sandbox" game where we can modify racks.
// Of course, special care should be taken to ignore this value if this
// is a regular game!
string full_rack = 5;
// event_index is the index of the event. This value should not be used for
// anything other than broadcast/"sandbox" games, and it will be used for
// editing previous moves. If used, the entire game until event_index will
// be truncated, so this must also be used with care!
int32 event_index = 6;
string tiles = 4 [ deprecated = true ];
// machine_letters is tiles, but in binary.
bytes machine_letters = 5;
}

// A GameRules is just the name of a board layout + the name of a letter
Expand Down
9 changes: 8 additions & 1 deletion liwords-ui/src/constants/alphabets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,14 @@ export const runesToUint8Array = (
}
}
if (!match) {
throw new Error('cannot convert ' + runes + ' to uint8array');
// Check if it's a through play.
// This is not very clean.
if (chars[i] === ThroughTileMarker) {
bts.push(0);
i++;
} else {
throw new Error('cannot convert ' + runes + ' to uint8array');
}
}
}

Expand Down
10 changes: 8 additions & 2 deletions liwords-ui/src/gameroom/board_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ export const BoardPanel = React.memo((props: Props) => {
switch (move) {
case 'exchange':
if (addl) {
moveEvt = exchangeMoveEvent(addl, gameID);
moveEvt = exchangeMoveEvent(addl, gameID, gameContext.alphabet);
}
break;
case 'pass':
Expand All @@ -341,7 +341,12 @@ export const BoardPanel = React.memo((props: Props) => {
moveEvt = challengeMoveEvent(gameID);
break;
case 'commit':
moveEvt = tilesetToMoveEvent(placedTiles, board, gameID);
moveEvt = tilesetToMoveEvent(
placedTiles,
board,
gameID,
gameContext.alphabet
);
if (!moveEvt) {
// this is an invalid play
return;
Expand All @@ -363,6 +368,7 @@ export const BoardPanel = React.memo((props: Props) => {
}
},
[
gameContext.alphabet,
gameContext.nickToPlayerOrder,
boardEditingMode,
examinableGameContext.onturn,
Expand Down
27 changes: 7 additions & 20 deletions liwords-ui/src/gen/api/proto/ipc/omgwords_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,30 +219,17 @@ export declare class ClientGameplayEvent extends Message<ClientGameplayEvent> {
* tiles that are being played (or exchanged). The `.` character is used
* for thru, and lowercase characters are used for blanks.
*
* @generated from field: string tiles = 4;
* @generated from field: string tiles = 4 [deprecated = true];
* @deprecated
*/
tiles: string;

/**
* full_rack is the rack that the play is being made from. Note that the
* server already knows the full rack, so this does not need to be provided,
* unless our game is a broadcast/"sandbox" game where we can modify racks.
* Of course, special care should be taken to ignore this value if this
* is a regular game!
*
* @generated from field: string full_rack = 5;
*/
fullRack: string;

/**
* event_index is the index of the event. This value should not be used for
* anything other than broadcast/"sandbox" games, and it will be used for
* editing previous moves. If used, the entire game until event_index will
* be truncated, so this must also be used with care!
* machine_letters is tiles, but in binary.
*
* @generated from field: int32 event_index = 6;
* @generated from field: bytes machine_letters = 5;
*/
eventIndex: number;
machineLetters: Uint8Array;

constructor(data?: PartialMessage<ClientGameplayEvent>);

Expand Down Expand Up @@ -304,8 +291,8 @@ export declare class GameRules extends Message<GameRules> {
boardLayoutName: string;

/**
* The supported letter distributions are english, french, norwegian, german,
* catalan. There are more to come!
* The supported letter distributions are english, french, norwegian, german.
* There are more to come!
*
* @generated from field: string letter_distribution_name = 2;
*/
Expand Down
3 changes: 1 addition & 2 deletions liwords-ui/src/gen/api/proto/ipc/omgwords_pb.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@ export const ClientGameplayEvent = proto3.makeMessageType(
{ no: 2, name: "game_id", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "position_coords", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 4, name: "tiles", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "full_rack", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 6, name: "event_index", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
{ no: 5, name: "machine_letters", kind: "scalar", T: 12 /* ScalarType.BYTES */ },
],
);

Expand Down
35 changes: 29 additions & 6 deletions liwords-ui/src/utils/cwgame/game_event.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EphemeralTile } from './common';
import { computeLeave, tilesetToMoveEvent } from './game_event';
import { Board } from './board';
import { StandardEnglishAlphabet } from '../../constants/alphabets';

const oxyTilesLayout = [
' PACIFYING ',
Expand Down Expand Up @@ -59,10 +60,17 @@ it('tests complex event', () => {
});
const board = new Board();
board.setTileLayout(oxyTilesLayout);
const evt = tilesetToMoveEvent(placedTiles, board, '');
const evt = tilesetToMoveEvent(
placedTiles,
board,
'',
StandardEnglishAlphabet
);
expect(evt).not.toBeNull();
expect(evt?.positionCoords).toEqual('A1');
expect(evt?.tiles).toEqual('OX.P...B..AZ..E');
expect(evt?.machineLetters).toEqual(
Uint8Array.from([15, 24, 0, 16, 0, 0, 0, 2, 0, 0, 1, 26, 0, 0, 5])
); // 'OX.P...B..AZ..E'
});

it('tests invalid play', () => {
Expand Down Expand Up @@ -100,7 +108,12 @@ it('tests invalid play', () => {
});
const board = new Board();
board.setTileLayout(oxyTilesLayout);
const evt = tilesetToMoveEvent(placedTiles, board, '');
const evt = tilesetToMoveEvent(
placedTiles,
board,
'',
StandardEnglishAlphabet
);
expect(evt).toBeNull();
});

Expand All @@ -123,7 +136,12 @@ it('should not commit undesignated blank', () => {
});
const board = new Board();
board.setTileLayout(oxyTilesLayout);
const evt = tilesetToMoveEvent(placedTiles, board, '');
const evt = tilesetToMoveEvent(
placedTiles,
board,
'',
StandardEnglishAlphabet
);
expect(evt).toBeNull();
});

Expand All @@ -146,10 +164,15 @@ it('tests event with blank', () => {
});
const board = new Board();
board.setTileLayout(oxyTilesLayout);
const evt = tilesetToMoveEvent(placedTiles, board, '');
const evt = tilesetToMoveEvent(
placedTiles,
board,
'',
StandardEnglishAlphabet
);
expect(evt).not.toBeNull();
expect(evt?.positionCoords).toEqual('5C');
expect(evt?.tiles).toEqual('.ImB');
expect(evt?.machineLetters).toEqual(Uint8Array.from([0, 9, 0x80 | 13, 2]));
});

it('tests computeLeave', () => {
Expand Down
15 changes: 11 additions & 4 deletions liwords-ui/src/utils/cwgame/game_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import {
ClientGameplayEvent_EventType,
PlayerInfo,
} from '../../gen/api/proto/ipc/omgwords_pb';
import { runesToUint8Array } from '../../constants/alphabets';
import { Alphabet } from '../../constants/alphabets';

export const ThroughTileMarker = '.';
// convert a set of ephemeral tiles to a protobuf game event.
export const tilesetToMoveEvent = (
tiles: Set<EphemeralTile>,
board: Board,
gameID: string
gameID: string,
alphabet: Alphabet
) => {
const ret = contiguousTilesFromTileSet(tiles, board);
if (ret === null) {
Expand Down Expand Up @@ -50,17 +53,21 @@ export const tilesetToMoveEvent = (

const evt = new ClientGameplayEvent({
positionCoords: wordPos,
tiles: wordStr,
machineLetters: runesToUint8Array(wordStr, alphabet),
type: ClientGameplayEvent_EventType.TILE_PLACEMENT,
gameId: gameID,
});

return evt;
};

export const exchangeMoveEvent = (rack: string, gameID: string) => {
export const exchangeMoveEvent = (
rack: string,
gameID: string,
alphabet: Alphabet
) => {
const evt = new ClientGameplayEvent({
tiles: rack,
machineLetters: runesToUint8Array(rack, alphabet),
type: ClientGameplayEvent_EventType.EXCHANGE,
gameId: gameID,
});
Expand Down
28 changes: 21 additions & 7 deletions pkg/cwgame/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,13 +490,21 @@ func clientEventToGameEvent(ctx context.Context, evt *ipc.ClientGameplayEvent, g
if err != nil {
return nil, err
}

if len(evt.Tiles) > 0 && len(evt.MachineLetters) > 0 {
return nil, errors.New("cannot specify both tiles and machineletters")
}
switch evt.Type {
case ipc.ClientGameplayEvent_TILE_PLACEMENT:
row, col, dir := fromBoardGameCoords(evt.PositionCoords)
mw, err := tilemapping.ToMachineLetters(evt.Tiles, dist.TileMapping())
if err != nil {
return nil, err
var mw []tilemapping.MachineLetter
var err error
if len(evt.Tiles) > 0 {
mw, err = tilemapping.ToMachineLetters(evt.Tiles, dist.TileMapping())
if err != nil {
return nil, err
}
} else {
mw = tilemapping.FromByteArr(evt.MachineLetters)
}
_, err = Leave(rackmw, mw)
if err != nil {
Expand All @@ -520,9 +528,15 @@ func clientEventToGameEvent(ctx context.Context, evt *ipc.ClientGameplayEvent, g
PlayerIndex: gdoc.PlayerOnTurn,
}, nil
case ipc.ClientGameplayEvent_EXCHANGE:
mw, err := tilemapping.ToMachineLetters(evt.Tiles, dist.TileMapping())
if err != nil {
return nil, err
var mw []tilemapping.MachineLetter
var err error
if len(evt.Tiles) > 0 {
mw, err = tilemapping.ToMachineLetters(evt.Tiles, dist.TileMapping())
if err != nil {
return nil, err
}
} else {
mw = tilemapping.FromByteArr(evt.MachineLetters)
}
_, err = Leave(rackmw, mw)
if err != nil {
Expand Down
Loading