diff --git a/src/app/haxe/ru/m/puzzlez/PuzzlezTheme.hx b/src/app/haxe/ru/m/puzzlez/PuzzlezTheme.hx index 81ad05b..eeea168 100644 --- a/src/app/haxe/ru/m/puzzlez/PuzzlezTheme.hx +++ b/src/app/haxe/ru/m/puzzlez/PuzzlezTheme.hx @@ -18,6 +18,7 @@ class PuzzlezTheme extends Theme { "restore" => "window-restore-solid.svg", "compress" => "compress-solid.svg", "expand" => "expand-solid.svg", + "spread" => "clone.svg", ]; public function new() { diff --git a/src/app/haxe/ru/m/puzzlez/view/GameFrame.hx b/src/app/haxe/ru/m/puzzlez/view/GameFrame.hx index ca81a22..4ec21e6 100644 --- a/src/app/haxe/ru/m/puzzlez/view/GameFrame.hx +++ b/src/app/haxe/ru/m/puzzlez/view/GameFrame.hx @@ -7,7 +7,9 @@ import hw.view.popup.ConfirmView; import promhx.Promise; import ru.m.puzzlez.image.Game; import ru.m.puzzlez.image.IGame; +import ru.m.puzzlez.proto.event.GameAction; import ru.m.puzzlez.proto.event.GameEvent; +import ru.m.puzzlez.proto.event.gameaction.Action; import ru.m.puzzlez.proto.game.GameState; import ru.m.puzzlez.proto.game.GameStatus; import ru.m.puzzlez.render.IRender; @@ -91,6 +93,16 @@ import ru.m.puzzlez.view.popup.PreviewPopup; }); } + private function shuffle():Void { + // TODO: playerId? + game.action(new GameAction().setAction(Action.TABLE_SHUFFLE).setPlayerId("local")); + } + + private function spread():Void { + // TODO: playerId? + game.action(new GameAction().setAction(Action.TABLE_SPREAD).setPlayerId("local")); + } + private function back():Void { (game.state.status == GameStatus.COMPLETE ? Promise.promise(true) : ConfirmView.confirm("Exit?")).then(result -> { if (result) { diff --git a/src/app/haxe/ru/m/puzzlez/view/GameFrame.yaml b/src/app/haxe/ru/m/puzzlez/view/GameFrame.yaml index 984ed2c..192a6aa 100644 --- a/src/app/haxe/ru/m/puzzlez/view/GameFrame.yaml +++ b/src/app/haxe/ru/m/puzzlez/view/GameFrame.yaml @@ -25,6 +25,12 @@ views: - $type: hw.view.form.ButtonView style: icon.restore +onPress: ~render.manager.reset() + - $type: hw.view.form.ButtonView + style: icon.spread + +onPress: ~shuffle() + - $type: hw.view.form.ButtonView + style: icon.spread + +onPress: ~spread() - $type: hw.view.form.ButtonView style: icon.setting geometry.margin.top: 30 diff --git a/src/app/resources/icon/clone.svg b/src/app/resources/icon/clone.svg new file mode 100644 index 0000000..e85aefc --- /dev/null +++ b/src/app/resources/icon/clone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/common/haxe/ru/m/ArrayUtil.hx b/src/common/haxe/ru/m/ArrayUtil.hx new file mode 100644 index 0000000..33e7d11 --- /dev/null +++ b/src/common/haxe/ru/m/ArrayUtil.hx @@ -0,0 +1,17 @@ +package ru.m; + +class ArrayUtil { + public static function shuffle(source:Array):Array { + var target:Array = source.slice(0); + var currentIndex = target.length; + + while (currentIndex != 0) { + var randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + var tmp = target[currentIndex]; + target[currentIndex] = target[randomIndex]; + target[randomIndex] = tmp; + } + return target; + } +} diff --git a/src/common/haxe/ru/m/puzzlez/image/Game.hx b/src/common/haxe/ru/m/puzzlez/image/Game.hx index 7a29cda..7fdf13d 100644 --- a/src/common/haxe/ru/m/puzzlez/image/Game.hx +++ b/src/common/haxe/ru/m/puzzlez/image/Game.hx @@ -50,6 +50,29 @@ class Game implements IGame { var x = bound + Math.random() * (state.preset.tableRect.width - part.rect.width - bound * 2); var y = bound + Math.random() * (state.preset.tableRect.height - part.rect.height - bound * 2); part.position = new PointExt(x, y); + events.emit(EventUtil.change(part)); + case _: + } + } + } + + private function spread():Void { + var partWidth = state.preset.imageRect.width / state.preset.grid.x; + var partHeight = state.preset.imageRect.height / state.preset.grid.y; + var bound = partWidth * 0.25; + var x = bound; + var y = bound; + var parts = ArrayUtil.shuffle(state.parts); + for (part in parts) { + switch part.location { + case PartLocation.TABLE: + part.position = new PointExt(x, y); + x += part.rect.width + bound; + if (x > state.preset.tableRect.width - partWidth - bound) { + x = bound; + y += part.rect.height + bound; + } + events.emit(EventUtil.change(part)); case _: } } @@ -107,6 +130,10 @@ class Game implements IGame { part.position = event.action.position; events.emit(EventUtil.change(part)); } + case Action.TABLE_SHUFFLE: + shuffle(); + case Action.TABLE_SPREAD: + spread(); } } } diff --git a/src/common/proto/event.proto b/src/common/proto/event.proto index a9b6175..dfda6b5 100644 --- a/src/common/proto/event.proto +++ b/src/common/proto/event.proto @@ -21,6 +21,8 @@ message GameAction { TAKE = 0; MOVE = 1; PUT = 2; + TABLE_SHUFFLE = 4; + TABLE_SPREAD = 3; } Action action = 3; ru.m.puzzlez.proto.core.Point position = 4;