16 puzzle game: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: added syntax colouring the hard way) |
|||
Line 625: | Line 625: | ||
puzzle16app(4) |
puzzle16app(4) |
||
</lang> |
</lang> |
||
=={{header|Nim}}== |
|||
{{trans|Julia}} |
|||
{{libheader|gintro}} |
|||
Not a direct translation as there are a lot of differences, but, at least, the graphical interface is similar and the logic is the same. |
|||
<lang Nim>import random, sequtils, strutils |
|||
import gintro/[glib, gobject, gtk, gio] |
|||
const |
|||
BoardSize = 4 |
|||
GridSize = BoardSize + 2 |
|||
Clock = "\u27f2" |
|||
AClock = "\u27f3" |
|||
type |
|||
Value = 1..16 |
|||
Puzzle = array[BoardSize, array[BoardSize, Value]] |
|||
PuzzleApp = ref object of Application |
|||
inOrder: Puzzle # Target grid. |
|||
puzzle: Puzzle # Current grid. |
|||
buttons: array[GridSize, array[GridSize, Button]] # Button grid. |
|||
won: bool # True if game won. |
|||
moves: Natural # Count of moves. |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc initPuzzle(puzzle: var Puzzle; data: openArray[Value]) = |
|||
## Initialize the puzzle with a list of values. |
|||
var i = 0 |
|||
for row in puzzle.mitems: |
|||
for cell in row.mitems: |
|||
cell = data[i] |
|||
inc i |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc showMessage(app: PuzzleApp) = |
|||
## As "gintro" doesn't provide "MessageDialog" yet, we will use a simple dialog. |
|||
let dialog = newDialog() |
|||
dialog.setModal(true) |
|||
let label = newLabel("You won in $# move(s)".format(app.moves)) |
|||
dialog.contentArea.add(label) |
|||
discard dialog.addButton("Ok", ord(ResponseType.ok)) |
|||
dialog.showAll() |
|||
discard dialog.run() |
|||
dialog.destroy() |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc onQuit(button: ToolButton; window: ApplicationWindow) = |
|||
## Procedure called when clicking quit button. |
|||
window.destroy() |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc rotateRow(puzzle: var Puzzle; row: Natural; left: bool) = |
|||
## Rotate a row left or right. |
|||
if left: |
|||
let first = puzzle[row][0] |
|||
for i in 1..puzzle.high: puzzle[row][i-1] = puzzle[row][i] |
|||
puzzle[row][^1] = first |
|||
else: |
|||
let last = puzzle[row][^1] |
|||
for i in countdown(puzzle.high, 1): puzzle[row][i] = puzzle[row][i-1] |
|||
puzzle[row][0] = last |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc rotateCol(puzzle: var Puzzle; col: Natural; up: bool) = |
|||
## Rotate a column up or down. |
|||
if up: |
|||
let first = puzzle[0][col] |
|||
for i in 1..puzzle.high: puzzle[i-1][col] = puzzle[i][col] |
|||
puzzle[^1][col] = first |
|||
else: |
|||
let last = puzzle[^1][col] |
|||
for i in countdown(puzzle[0].high, 1): puzzle[i][col] =puzzle[i-1][col] |
|||
puzzle[0][col] = last |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc findRowCol(app: PuzzleApp; button: Button): (int, int) = |
|||
## Find the row and column of a button. |
|||
for i in [0, BoardSize+1]: |
|||
for j in 1..Boardsize: |
|||
if app.buttons[i][j] == button: return (i, j) |
|||
for j in [0, BoardSize+1]: |
|||
for i in 1..Boardsize: |
|||
if app.buttons[i][j] == button: return (i, j) |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc update(app: PuzzleApp) = |
|||
## Update the grid. |
|||
for i in 0..BoardSize+1: |
|||
for j in 0..BoardSize+1: |
|||
if j in 1..BoardSize: |
|||
if i == 0: |
|||
app.buttons[i][j].setLabel(Clock) |
|||
elif i == BoardSize + 1: |
|||
app.buttons[i][j].setLabel(AClock) |
|||
else: |
|||
app.buttons[i][j].setLabel($app.puzzle[i-1][j-1]) |
|||
elif i in 1..BoardSize: |
|||
if j == 0: |
|||
app.buttons[i][j].setLabel(Clock) |
|||
elif j == BoardSize + 1: |
|||
app.buttons[i][j].setLabel(AClock) |
|||
if app.puzzle == app.inOrder: |
|||
app.won = true |
|||
app.showMessage() |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc onClick(button: Button; app: PuzzleApp) = |
|||
## Procedure called when the user cliked a grid button. |
|||
if not app.won: |
|||
inc app.moves |
|||
let (i, j) = app.findRowCol(button) |
|||
if i == 0: |
|||
app.puzzle.rotateCol(j - 1, true) |
|||
elif i == BoardSize + 1: |
|||
app.puzzle.rotateCol(j - 1, false) |
|||
elif j == 0: |
|||
app.puzzle.rotateRow(i - 1, true) |
|||
elif j == BoardSize + 1: |
|||
app.puzzle.rotateRow(i - 1, false) |
|||
app.update() |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc newGame(button: ToolButton; app: PuzzleApp) = |
|||
## Prepare a new game. |
|||
var values = toSeq(Value.low..Value.high) |
|||
values.shuffle() |
|||
app.puzzle.initPuzzle(values) |
|||
app.won = false |
|||
app.update() |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc activate(app: PuzzleApp) = |
|||
## Activate the application. |
|||
let window = app.newApplicationWindow() |
|||
window.setTitle("16 puzzle game") |
|||
window.setSizeRequest(300, 340) |
|||
let box = newBox(Orientation.vertical, 0) |
|||
window.add box |
|||
let toolbar = newToolbar() |
|||
let newGameButton = newToolButton(label = "New game") |
|||
toolbar.insert(newGameButton, 0) |
|||
let quitButton = newToolButton(label = "Quit") |
|||
toolbar.insert(quitButton, 1) |
|||
box.add toolbar |
|||
let grid = newGrid() |
|||
box.add grid |
|||
for i in 0..BoardSize+1: |
|||
for j in 0..BoardSize+1: |
|||
let button = newButton() |
|||
button.setHexpand(true) |
|||
button.setVexpand(true) |
|||
app.buttons[i][j] = button |
|||
grid.attach(button, j, i, 1, 1) |
|||
var values = toSeq(Value.low..Value.high) |
|||
app.inOrder.initPuzzle(values) |
|||
values.shuffle() |
|||
app.puzzle.initPuzzle(values) |
|||
for i in [0, BoardSize + 1]: |
|||
for j in 1..BoardSize: |
|||
app.buttons[i][j].connect("clicked", onClick, app) |
|||
for j in [0, BoardSize + 1]: |
|||
for i in 1..BoardSize: |
|||
app.buttons[i][j].connect("clicked", onClick, app) |
|||
newGameButton.connect("clicked", newGame, app) |
|||
quitButton.connect("clicked", onQuit, window) |
|||
app.won = false |
|||
app.update() |
|||
window.showAll() |
|||
#——————————————————————————————————————————————————————————————————————————————————————————————————— |
|||
randomize() |
|||
let app = newApplication(PuzzleApp, "Rosetta.Puzzle16Game") |
|||
discard app.connect("activate", activate) |
|||
discard app.run()</lang> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |