15 puzzle game in 3D: Difference between revisions

Added a suitable task description (there wasn't one before) and a Go entry.
m (moved <lang Ring> down)
(Added a suitable task description (there wasn't one before) and a Go entry.)
Line 1:
{{draft task}}
;Task
Create either a 15 puzzle game or an 8 puzzle game in your language using cubes rather than squares to represent the tiles (including the blank tile). The 'cuboid look' may be simulated rather than using actual 3D graphics and the cubes may either rotate or remain static.
 
This should be a playable game as opposed to a program which automatically attempts to find a solution without user intervention.
Video: [https://www.google.com/url?q=https%3A%2F%2F1drv.ms%2Fv%2Fs!AqDUIunCqVnIg08QfFw1EMomJax7&sa=D&sntz=1&usg=AFQjCNEPoUrKz3LEpuDMg_Xn0aq5yBUChA 15 Puzzle Game in 3D]
 
;References
* Article: [https://en.wikipedia.org/wiki/15_puzzle Wikipedia 15 puzzle].
* Video: [https://www.google.com/url?q=https%3A%2F%2F1drv.ms%2Fv%2Fs!AqDUIunCqVnIg08QfFw1EMomJax7&sa=D&sntz=1&usg=AFQjCNEPoUrKz3LEpuDMg_Xn0aq5yBUChA 15 Puzzle Game in 3D] for the Ring entry.
 
* Necessary files: [https://www.dropbox.com/s/8abbcbunkpcuvkl/fifteenpuzzle3d.zip?dl=0 Files for 15 Puzzle Game in 3D] as used by the Ring entry.
 
 
 
=={{header|Go}}==
{{libheader|raylib-go}}
<br>
Despite the name of the task, it appears that the author's Ring entry is actually producing an '8 puzzle' game and that the 3D aspect is handled by replacing the usual squares with colored, numbered cubes which rotate in space.
 
The following produces instead a '15 puzzle' game and the 3D aspect is again handled by using colored, numbered cubes. However, the cubes do not rotate (I found this very distracting when playing the game) and the 3D look is simulated by drawing regular hexagons with inner lines drawn between the appropriate vertices to make them look like cubes. A white numberless cube represents the blank square in a normal game.
 
The game is controlled by the arrow keys (mouse movement is not supported) which move the white cube left, right, up or down exchanging positions with the colored cube already occupying that position. The number of moves is continually updated and, if the player is eventually successful in assembling the cubes in order, an appropriate message is displayed, the white cube changes to dark green and displays the number 16.
<lang go>package main
 
import (
"fmt"
"github.com/gen2brain/raylib-go/raylib"
"math"
"math/rand"
"strconv"
"time"
)
 
var palette = []rl.Color{
rl.Blue,
rl.Green,
rl.Red,
rl.SkyBlue,
rl.Magenta,
rl.Gray,
rl.Lime,
rl.Purple,
rl.Violet,
rl.Pink,
rl.Gold,
rl.Orange,
rl.Maroon,
rl.Beige,
rl.Brown,
rl.RayWhite,
}
 
var (
screenWidth = int32(960)
screenHeight = int32(840)
radius = screenHeight / 14
fontSize = 2 * radius / 5
angle = math.Pi / 6
incr = 2 * angle
blank = 15
moves = 0
gameOver = false
)
 
var (
centers [16]rl.Vector2
cubes [16]int
)
 
func init() {
for i := 0; i < 16; i++ {
cubes[i] = i
}
}
 
func drawCube(n, pos int) {
r := float32(radius)
rl.DrawPoly(centers[pos], 6, r, 0, palette[n])
cx, cy := centers[pos].X, centers[pos].Y
for i := 1; i <= 5; i += 2 {
fi := float64(i)
vx := int32(r*float32(math.Cos(angle+fi*incr)) + cx)
vy := int32(r*float32(math.Sin(angle+fi*incr)) + cy)
rl.DrawLine(int32(cx), int32(cy), vx, vy, rl.Black)
}
ns := ""
if n < 15 || gameOver {
ns = strconv.Itoa(n + 1)
}
hr, er, tqr := r/2, r/8, 0.75*r
rl.DrawText(ns, int32(cx+hr-er), int32(cy), fontSize, rl.RayWhite)
rl.DrawText(ns, int32(cx-hr-er), int32(cy), fontSize, rl.RayWhite)
rl.DrawText(ns, int32(cx-er), int32(cy-tqr), fontSize, rl.RayWhite)
}
 
func updateGame() {
if gameOver {
return
} else if rl.IsKeyPressed(rl.KeyLeft) {
if blank%4 != 0 {
cubes[blank], cubes[blank-1] = cubes[blank-1], cubes[blank]
blank--
moves++
}
} else if rl.IsKeyPressed(rl.KeyRight) {
if (blank+1)%4 != 0 {
cubes[blank], cubes[blank+1] = cubes[blank+1], cubes[blank]
blank++
moves++
}
} else if rl.IsKeyPressed(rl.KeyUp) {
if blank > 3 {
cubes[blank], cubes[blank-4] = cubes[blank-4], cubes[blank]
blank -= 4
moves++
}
} else if rl.IsKeyPressed(rl.KeyDown) {
if blank < 12 {
cubes[blank], cubes[blank+4] = cubes[blank+4], cubes[blank]
blank += 4
moves++
}
}
}
 
func completed() bool {
for i := 0; i < 16; i++ {
if cubes[i] != i {
return false
}
}
palette[15] = rl.DarkGreen
gameOver = true
return true
}
 
func main() {
rand.Seed(time.Now().UnixNano())
rand.Shuffle(15, func(i, j int) {
cubes[i], cubes[j] = cubes[j], cubes[i]
})
rl.InitWindow(screenWidth, screenHeight, "15-puzzle game using 3D cubes")
rl.SetTargetFPS(60)
var x, y = float32(screenWidth) / 10, float32(radius)
for i := 0; i < 4; i++ {
cx := 2 * x * float32(i+1)
for j := 0; j < 4; j++ {
cy := (x + y) * float32(j+1)
centers[j*4+i] = rl.NewVector2(cx, cy)
}
}
 
for !rl.WindowShouldClose() {
rl.BeginDrawing()
rl.ClearBackground(rl.Black)
for i := 0; i < 16; i++ {
drawCube(cubes[i], i)
}
 
if !completed() {
m := fmt.Sprintf("Moves = %d", moves)
rl.DrawText(m, 4*int32(x), 13*int32(y), fontSize, rl.RayWhite)
} else {
m := fmt.Sprintf("You've completed the puzzle in %d moves!", moves)
rl.DrawText(m, 3*int32(x), 13*int32(y), fontSize, rl.RayWhite)
}
rl.EndDrawing()
updateGame()
}
 
rl.CloseWindow()
}</lang>
 
Necessary files: [https://www.dropbox.com/s/8abbcbunkpcuvkl/fifteenpuzzle3d.zip?dl=0 Files for 15 Puzzle Game in 3D]
 
=={{header|Ring}}==
9,485

edits