Add show/hide bomb
This commit is contained in:
parent
8c4507f6b4
commit
14a81762ac
|
@ -35,6 +35,8 @@ function useSender(sendNote: (r: ClientNote) => void, version: number): Sender {
|
||||||
changeTurnTime: (seconds: number) => sendNote({ method: 'changeTurnTime', version, params: { seconds } }),
|
changeTurnTime: (seconds: number) => sendNote({ method: 'changeTurnTime', version, params: { seconds } }),
|
||||||
addPacks: (packs: WordPack[]) => sendNote({ method: 'addPacks', version, params: { packs } }),
|
addPacks: (packs: WordPack[]) => sendNote({ method: 'addPacks', version, params: { packs } }),
|
||||||
removePack: (num: number) => sendNote({ method: 'removePack', version, params: { num } }),
|
removePack: (num: number) => sendNote({ method: 'removePack', version, params: { num } }),
|
||||||
|
changeHideBomb: (hideBomb: boolean) =>
|
||||||
|
sendNote({ method: 'changeHideBomb', version, params: { hideBomb } }),
|
||||||
};
|
};
|
||||||
}, [sendNote, version]);
|
}, [sendNote, version]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,18 @@ import {
|
||||||
useTheme,
|
useTheme,
|
||||||
} from '@material-ui/core';
|
} from '@material-ui/core';
|
||||||
import { green, orange } from '@material-ui/core/colors';
|
import { green, orange } from '@material-ui/core/colors';
|
||||||
import { Add, ArrowBack, Delete, Link, Person, Search, Timer, TimerOff } from '@material-ui/icons';
|
import {
|
||||||
|
Add,
|
||||||
|
ArrowBack,
|
||||||
|
Delete,
|
||||||
|
Link,
|
||||||
|
Person,
|
||||||
|
Search,
|
||||||
|
Timer,
|
||||||
|
TimerOff,
|
||||||
|
Visibility,
|
||||||
|
VisibilityOff,
|
||||||
|
} from '@material-ui/icons';
|
||||||
import { ok as assertTrue } from 'assert';
|
import { ok as assertTrue } from 'assert';
|
||||||
import isArray from 'lodash/isArray';
|
import isArray from 'lodash/isArray';
|
||||||
import range from 'lodash/range';
|
import range from 'lodash/range';
|
||||||
|
@ -39,6 +50,7 @@ export interface Sender {
|
||||||
changeTurnTime: (seconds: number) => void;
|
changeTurnTime: (seconds: number) => void;
|
||||||
addPacks: (packs: { name: string; words: string[] }[]) => void;
|
addPacks: (packs: { name: string; words: string[] }[]) => void;
|
||||||
removePack: (num: number) => void;
|
removePack: (num: number) => void;
|
||||||
|
changeHideBomb: (HideBomb: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GameViewProps {
|
export interface GameViewProps {
|
||||||
|
@ -415,12 +427,9 @@ const Footer = ({ send, state, pState }: GameViewProps) => {
|
||||||
const end = isDefined(state.winner);
|
const end = isDefined(state.winner);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container direction="row" justify="space-between" alignItems="flex-start" spacing={2}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignContent: 'flex-start', flexWrap: 'wrap' }}>
|
||||||
<Grid item xs style={{ textAlign: 'left' }}>
|
<div style={{ display: 'flex', alignContent: 'flex-start', flexWrap: 'wrap' }}>
|
||||||
<ButtonGroup
|
<ButtonGroup variant="outlined" style={{ marginBottom: '0.5rem', marginRight: '0.5rem' }}>
|
||||||
variant="outlined"
|
|
||||||
style={{ marginBottom: '0.5rem', marginRight: '0.5rem', display: 'inline' }}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant={pState.spymaster ? undefined : 'contained'}
|
variant={pState.spymaster ? undefined : 'contained'}
|
||||||
|
@ -440,10 +449,25 @@ const Footer = ({ send, state, pState }: GameViewProps) => {
|
||||||
Spymaster
|
Spymaster
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
<ButtonGroup
|
<ButtonGroup variant="outlined" style={{ marginBottom: '0.5rem', marginRight: '0.5rem' }}>
|
||||||
variant="outlined"
|
<Button
|
||||||
style={{ marginBottom: '0.5rem', marginRight: '0.5rem', display: 'inline' }}
|
type="button"
|
||||||
>
|
variant={state.hideBomb ? undefined : 'contained'}
|
||||||
|
onClick={() => send.changeHideBomb(false)}
|
||||||
|
startIcon={<Visibility />}
|
||||||
|
>
|
||||||
|
Show bomb
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant={state.hideBomb ? 'contained' : undefined}
|
||||||
|
onClick={() => send.changeHideBomb(true)}
|
||||||
|
startIcon={<VisibilityOff />}
|
||||||
|
>
|
||||||
|
Hide bomb
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
<ButtonGroup variant="outlined" style={{ marginBottom: '0.5rem', marginRight: '0.5rem' }}>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant={isDefined(state.timer) ? undefined : 'contained'}
|
variant={isDefined(state.timer) ? undefined : 'contained'}
|
||||||
|
@ -459,8 +483,8 @@ const Footer = ({ send, state, pState }: GameViewProps) => {
|
||||||
<Timer />
|
<Timer />
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</Grid>
|
</div>
|
||||||
<Grid item xs style={{ textAlign: 'right' }}>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant={end ? 'contained' : 'outlined'}
|
variant={end ? 'contained' : 'outlined'}
|
||||||
|
@ -470,8 +494,8 @@ const Footer = ({ send, state, pState }: GameViewProps) => {
|
||||||
>
|
>
|
||||||
New game
|
New game
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</div>
|
||||||
</Grid>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -317,6 +317,7 @@ const props = {
|
||||||
],
|
],
|
||||||
turnTime: 0,
|
turnTime: 0,
|
||||||
turnEnd: null,
|
turnEnd: null,
|
||||||
|
hideBomb: false,
|
||||||
},
|
},
|
||||||
pState: {
|
pState: {
|
||||||
playerID: 'acb830de-80e2-4eba-9b56-81b089fd3f12',
|
playerID: 'acb830de-80e2-4eba-9b56-81b089fd3f12',
|
||||||
|
|
|
@ -76,6 +76,10 @@ export const ClientNote = myzod
|
||||||
method: myzod.literal('removePack'),
|
method: myzod.literal('removePack'),
|
||||||
params: myzod.object({ num: myzod.number() }),
|
params: myzod.object({ num: myzod.number() }),
|
||||||
}),
|
}),
|
||||||
|
myzod.object({
|
||||||
|
method: myzod.literal('changeHideBomb'),
|
||||||
|
params: myzod.object({ hideBomb: myzod.boolean() }),
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -129,6 +133,7 @@ export const State = myzod.object({
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
timer: StateTimer.optional().nullable(),
|
timer: StateTimer.optional().nullable(),
|
||||||
|
hideBomb: myzod.boolean(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ServerNote = Infer<typeof ServerNote>;
|
export type ServerNote = Infer<typeof ServerNote>;
|
||||||
|
|
|
@ -174,6 +174,13 @@ type ServerNote struct {
|
||||||
Params interface{} `json:"params"`
|
Params interface{} `json:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ChangeHideBombMethod = ClientMethod("changeHideBomb")
|
||||||
|
|
||||||
|
//easyjson:json
|
||||||
|
type ChangeHideBombParams struct {
|
||||||
|
HideBomb bool `json:"hideBomb"`
|
||||||
|
}
|
||||||
|
|
||||||
func StateNote(s *State) ServerNote {
|
func StateNote(s *State) ServerNote {
|
||||||
return ServerNote{
|
return ServerNote{
|
||||||
Method: "state",
|
Method: "state",
|
||||||
|
@ -191,6 +198,7 @@ type State struct {
|
||||||
WordsLeft []int `json:"wordsLeft"`
|
WordsLeft []int `json:"wordsLeft"`
|
||||||
Lists []*StateWordList `json:"lists"`
|
Lists []*StateWordList `json:"lists"`
|
||||||
Timer *StateTimer `json:"timer"`
|
Timer *StateTimer `json:"timer"`
|
||||||
|
HideBomb bool `json:"hideBomb"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//easyjson:json
|
//easyjson:json
|
||||||
|
|
|
@ -804,6 +804,8 @@ func easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol7(in *jlexer.L
|
||||||
}
|
}
|
||||||
(*out.Timer).UnmarshalEasyJSON(in)
|
(*out.Timer).UnmarshalEasyJSON(in)
|
||||||
}
|
}
|
||||||
|
case "hideBomb":
|
||||||
|
out.HideBomb = bool(in.Bool())
|
||||||
default:
|
default:
|
||||||
in.AddError(&jlexer.LexerError{
|
in.AddError(&jlexer.LexerError{
|
||||||
Offset: in.GetPos(),
|
Offset: in.GetPos(),
|
||||||
|
@ -948,6 +950,11 @@ func easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol7(out *jwriter
|
||||||
(*in.Timer).MarshalEasyJSON(out)
|
(*in.Timer).MarshalEasyJSON(out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const prefix string = ",\"hideBomb\":"
|
||||||
|
out.RawString(prefix)
|
||||||
|
out.Bool(bool(in.HideBomb))
|
||||||
|
}
|
||||||
out.RawByte('}')
|
out.RawByte('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2093,7 +2100,77 @@ func (v *ChangeNicknameParams) UnmarshalJSON(data []byte) error {
|
||||||
func (v *ChangeNicknameParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *ChangeNicknameParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol22(l, v)
|
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol22(l, v)
|
||||||
}
|
}
|
||||||
func easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(in *jlexer.Lexer, out *AddPacksParams) {
|
func easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(in *jlexer.Lexer, out *ChangeHideBombParams) {
|
||||||
|
isTopLevel := in.IsStart()
|
||||||
|
if in.IsNull() {
|
||||||
|
if isTopLevel {
|
||||||
|
in.Consumed()
|
||||||
|
}
|
||||||
|
in.Skip()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
in.Delim('{')
|
||||||
|
for !in.IsDelim('}') {
|
||||||
|
key := in.UnsafeString()
|
||||||
|
in.WantColon()
|
||||||
|
if in.IsNull() {
|
||||||
|
in.Skip()
|
||||||
|
in.WantComma()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch key {
|
||||||
|
case "hideBomb":
|
||||||
|
out.HideBomb = bool(in.Bool())
|
||||||
|
default:
|
||||||
|
in.AddError(&jlexer.LexerError{
|
||||||
|
Offset: in.GetPos(),
|
||||||
|
Reason: "unknown field",
|
||||||
|
Data: key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
in.WantComma()
|
||||||
|
}
|
||||||
|
in.Delim('}')
|
||||||
|
if isTopLevel {
|
||||||
|
in.Consumed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(out *jwriter.Writer, in ChangeHideBombParams) {
|
||||||
|
out.RawByte('{')
|
||||||
|
first := true
|
||||||
|
_ = first
|
||||||
|
{
|
||||||
|
const prefix string = ",\"hideBomb\":"
|
||||||
|
out.RawString(prefix[1:])
|
||||||
|
out.Bool(bool(in.HideBomb))
|
||||||
|
}
|
||||||
|
out.RawByte('}')
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON supports json.Marshaler interface
|
||||||
|
func (v ChangeHideBombParams) MarshalJSON() ([]byte, error) {
|
||||||
|
w := jwriter.Writer{}
|
||||||
|
easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(&w, v)
|
||||||
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
|
func (v ChangeHideBombParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
|
easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(w, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
|
func (v *ChangeHideBombParams) UnmarshalJSON(data []byte) error {
|
||||||
|
r := jlexer.Lexer{Data: data}
|
||||||
|
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(&r, v)
|
||||||
|
return r.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
|
func (v *ChangeHideBombParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
|
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(l, v)
|
||||||
|
}
|
||||||
|
func easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol24(in *jlexer.Lexer, out *AddPacksParams) {
|
||||||
isTopLevel := in.IsStart()
|
isTopLevel := in.IsStart()
|
||||||
if in.IsNull() {
|
if in.IsNull() {
|
||||||
if isTopLevel {
|
if isTopLevel {
|
||||||
|
@ -2158,7 +2235,7 @@ func easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(in *jlexer.
|
||||||
in.Consumed()
|
in.Consumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(out *jwriter.Writer, in AddPacksParams) {
|
func easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol24(out *jwriter.Writer, in AddPacksParams) {
|
||||||
out.RawByte('{')
|
out.RawByte('{')
|
||||||
first := true
|
first := true
|
||||||
_ = first
|
_ = first
|
||||||
|
@ -2184,25 +2261,25 @@ func easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(out *jwrite
|
||||||
// MarshalJSON supports json.Marshaler interface
|
// MarshalJSON supports json.Marshaler interface
|
||||||
func (v AddPacksParams) MarshalJSON() ([]byte, error) {
|
func (v AddPacksParams) MarshalJSON() ([]byte, error) {
|
||||||
w := jwriter.Writer{}
|
w := jwriter.Writer{}
|
||||||
easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(&w, v)
|
easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol24(&w, v)
|
||||||
return w.Buffer.BuildBytes(), w.Error
|
return w.Buffer.BuildBytes(), w.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalEasyJSON supports easyjson.Marshaler interface
|
// MarshalEasyJSON supports easyjson.Marshaler interface
|
||||||
func (v AddPacksParams) MarshalEasyJSON(w *jwriter.Writer) {
|
func (v AddPacksParams) MarshalEasyJSON(w *jwriter.Writer) {
|
||||||
easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol23(w, v)
|
easyjsonE4425964EncodeGithubComZikaerohCodiesInternalProtocol24(w, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalJSON supports json.Unmarshaler interface
|
// UnmarshalJSON supports json.Unmarshaler interface
|
||||||
func (v *AddPacksParams) UnmarshalJSON(data []byte) error {
|
func (v *AddPacksParams) UnmarshalJSON(data []byte) error {
|
||||||
r := jlexer.Lexer{Data: data}
|
r := jlexer.Lexer{Data: data}
|
||||||
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(&r, v)
|
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol24(&r, v)
|
||||||
return r.Error()
|
return r.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
|
||||||
func (v *AddPacksParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
func (v *AddPacksParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
|
||||||
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol23(l, v)
|
easyjsonE4425964DecodeGithubComZikaerohCodiesInternalProtocol24(l, v)
|
||||||
}
|
}
|
||||||
func easyjsonE4425964Decode(in *jlexer.Lexer, out *struct {
|
func easyjsonE4425964Decode(in *jlexer.Lexer, out *struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
|
@ -214,6 +214,8 @@ type Room struct {
|
||||||
turnSeconds int
|
turnSeconds int
|
||||||
turnDeadline *time.Time
|
turnDeadline *time.Time
|
||||||
turnTimer *time.Timer
|
turnTimer *time.Timer
|
||||||
|
|
||||||
|
hideBomb bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type noteSender func(protocol.ServerNote)
|
type noteSender func(protocol.ServerNote)
|
||||||
|
@ -411,6 +413,13 @@ func (r *Room) handleNote(playerID game.PlayerID, note *protocol.ClientNote) err
|
||||||
}
|
}
|
||||||
r.room.RemovePack(params.Num)
|
r.room.RemovePack(params.Num)
|
||||||
|
|
||||||
|
case protocol.ChangeHideBombMethod:
|
||||||
|
var params protocol.ChangeHideBombParams
|
||||||
|
if err := json.Unmarshal(note.Params, ¶ms); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.changeHideBomb(params.HideBomb)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Printf("unhandled method: %s", note.Method)
|
log.Printf("unhandled method: %s", note.Method)
|
||||||
}
|
}
|
||||||
|
@ -469,6 +478,7 @@ func (r *Room) createRoomState(spymaster bool) *protocol.State {
|
||||||
Board: make([][]*protocol.StateTile, room.Board.Rows),
|
Board: make([][]*protocol.StateTile, room.Board.Rows),
|
||||||
WordsLeft: room.Board.WordCounts,
|
WordsLeft: room.Board.WordCounts,
|
||||||
Lists: make([]*protocol.StateWordList, len(room.WordLists)),
|
Lists: make([]*protocol.StateWordList, len(room.WordLists)),
|
||||||
|
HideBomb: r.hideBomb,
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.turnDeadline != nil {
|
if r.turnDeadline != nil {
|
||||||
|
@ -503,11 +513,17 @@ func (r *Room) createRoomState(spymaster bool) *protocol.State {
|
||||||
}
|
}
|
||||||
|
|
||||||
if spymaster || tile.Revealed || room.Winner != nil {
|
if spymaster || tile.Revealed || room.Winner != nil {
|
||||||
sTile.View = &protocol.StateView{
|
view := &protocol.StateView{
|
||||||
Team: tile.Team,
|
Team: tile.Team,
|
||||||
Neutral: tile.Neutral,
|
Neutral: tile.Neutral,
|
||||||
Bomb: tile.Bomb,
|
Bomb: tile.Bomb,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !tile.Revealed && room.Winner != nil && r.hideBomb {
|
||||||
|
view.Bomb = false
|
||||||
|
}
|
||||||
|
|
||||||
|
sTile.View = view
|
||||||
}
|
}
|
||||||
|
|
||||||
tiles[col] = sTile
|
tiles[col] = sTile
|
||||||
|
@ -608,3 +624,14 @@ func (r *Room) startTimer() {
|
||||||
r.turnDeadline = &deadline
|
r.turnDeadline = &deadline
|
||||||
r.turnTimer = time.AfterFunc(dur, r.timerEndTurn)
|
r.turnTimer = time.AfterFunc(dur, r.timerEndTurn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be called with r.mu locked.
|
||||||
|
func (r *Room) changeHideBomb(HideBomb bool) {
|
||||||
|
if r.hideBomb == HideBomb {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.hideBomb = true
|
||||||
|
r.room.Version++
|
||||||
|
r.sendAll()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue