-
Notifications
You must be signed in to change notification settings - Fork 1
/
game2.js
165 lines (155 loc) · 5 KB
/
game2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Game of 15
//
var boardDim = 4; // Configurable board size - go nuts!
exports.View =
{
title: "Game of 15",
elements:
[
{ control: "text", value: "Tap a tile to shift that tile, row, or column toward the empty space until all tiles are in order. All game state is actually in a Synchro app running on the server.", width: "*" },
{ control: "rectangle", width: "*", height: 5, color: "Black" },
{ control: "stackpanel", orientation: "Vertical", margin: 0, width: "*", contents: [
{ control: "text", value: "Put the Squares in Order", fontsize: 12, horizontalAlignment: "Center" },
{ control: "stackpanel", orientation: "Horizontal", margin: 0, horizontalAlignment: "Center", binding: { foreach: "board" }, contents: [
{ control: "border", background: "{background}", height: 75, width: 75, margin: 5, binding: { foreach: "$data", onTap: { command: "squareTapped", row: "{$parent.$index}", col: "{$index}" } }, contents: [
{ control: "text", value: "{number}", horizontalAlignment: "Center", verticalAlignment: "Center", margin: 0 },
]}
] },
{ control: "text", value: "Turns: {turnCount}", fontsize: "12", horizontalAlignment: "Center" }
] },
]
}
exports.InitializeViewModel = function(context, session)
{
var viewModel =
{
turnCount: 0,
blankRow: boardDim-1,
blankCol: boardDim-1
}
// Populate the board (not all random boards are solvable, so we start with a solved board, then scramble it).
//
var curr = 1;
viewModel.board = new Array(boardDim);
for (var row = 0; row < boardDim; row++)
{
viewModel.board[row] = new Array(boardDim);
for (var col = 0; col < boardDim; col++)
{
if (curr < (boardDim * boardDim))
{
viewModel.board[row][col] = { number: curr++, background: "Orange" };
}
else
{
viewModel.board[row][col] = { };
}
}
}
// Scramble the board
//
for (var i = 0; i < 250; i++)
{
var newBlankRow = viewModel.blankRow;
var newBlankCol = viewModel.blankCol;
if (Math.random() > 0.5)
{
// Pick a new row at random
while (newBlankRow == viewModel.blankRow)
{
newBlankRow = Math.floor(Math.random() * boardDim);
}
}
else
{
// Pick a new col at random
while (newBlankCol == viewModel.blankCol)
{
newBlankCol = Math.floor(Math.random() * boardDim);
}
}
toggle(viewModel, newBlankRow, newBlankCol);
}
return viewModel;
}
function isSolved(board)
{
for (var row = 0; row < boardDim; row++)
{
for (var col = 0; col < boardDim; col++)
{
if ((row == boardDim-1) && (col == boardDim-1) && !board[row][col].number)
{
return true; // Got to the end and found empty square
}
else if (((row * boardDim) + col + 1) != board[row][col].number)
{
return false; // Found a square out of position
}
}
}
return false;
}
function toggle(viewModel, row, col)
{
if ((row == viewModel.blankRow) && (col == viewModel.blankCol))
{
return false; // Selected location is already blank, NOOP
}
else if (row == viewModel.blankRow)
{
if (col < viewModel.blankCol) // Shift cells left
{
for (var i = viewModel.blankCol; i > col; i--)
{
viewModel.board[row][i] = viewModel.board[row][i-1];
}
}
else // Shift cells right
{
for (var i = viewModel.blankCol; i < col; i++)
{
viewModel.board[row][i] = viewModel.board[row][i+1];
}
}
}
else if (col == viewModel.blankCol)
{
if (row < viewModel.blankRow) // Shift cells up
{
for (var i = viewModel.blankRow; i > row; i--)
{
viewModel.board[i][col] = viewModel.board[i-1][col];
}
}
else // Shift cells down
{
for (var i = viewModel.blankRow; i < row; i++)
{
viewModel.board[i][col] = viewModel.board[i+1][col];
}
}
}
else
{
return false; // Invalid turn (blank is not on the chosen row/col), NOOP
}
viewModel.board[row][col] = {};
viewModel.blankRow = row;
viewModel.blankCol = col;
return true;
}
exports.Commands =
{
squareTapped: function(context, session, viewModel, params)
{
if (toggle(viewModel, params.row, params.col))
{
viewModel.turnCount++;
if (isSolved(viewModel.board))
{
return Synchro.showMessage(context, { message: "Congrats! You solved it!" });
}
}
}
}