16 puzzle game: Difference between revisions

m (→‎{{header|Phix}}: added syntax colouring the hard way)
Line 625:
puzzle16app(4)
</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}}==
Anonymous user