Snake: Difference between revisions

Content deleted Content added
Edmund (talk | contribs)
Added ZX Spectrum Basic
PureFox (talk | contribs)
Added Kotlin
Line 221: Line 221:
}
}
</lang>
</lang>

=={{header|Kotlin}}==
{{trans|C++}}
{{works with|Windows 10}}
<lang scala>// Kotlin Native v0.5

import kotlinx.cinterop.*
import platform.posix.*
import platform.windows.*

const val WID = 60
const val HEI = 30
const val MAX_LEN = 600
const val NUL = '\u0000'

enum class Dir { NORTH, EAST, SOUTH, WEST }

class Snake {
val console: HANDLE
var alive = false
val brd = CharArray(WID * HEI)
var dir = Dir.NORTH
val snk = nativeHeap.allocArray<COORD>(MAX_LEN)
lateinit var head: COORD
var tailIdx = 0
var headIdx = 0
var points = 0

init {
console = GetStdHandle(STD_OUTPUT_HANDLE)!!
SetConsoleTitleW("Snake")
memScoped {
val coord = alloc<COORD>().apply { X = (WID + 1).toShort(); Y = (HEI + 2).toShort() }
SetConsoleScreenBufferSize(console, coord.readValue())
val rc = alloc<SMALL_RECT>().apply {
Left = 0; Top = 0; Right = WID.toShort(); Bottom = (HEI + 1).toShort()
}
SetConsoleWindowInfo(console, TRUE, rc.ptr)
val ci = alloc<CONSOLE_CURSOR_INFO>().apply { dwSize = 1; bVisible = FALSE }
SetConsoleCursorInfo(console, ci.ptr)
}
}

fun play() {
while (true) {
createfield()
alive = true
while (alive) {
drawfield()
readKey()
moveSnake()
Sleep(50)
}
memScoped {
val c = alloc<COORD>().apply { X = 0; Y = (HEI + 1).toShort() }
SetConsoleCursorPosition(console, c.readValue())
}
SetConsoleTextAttribute(console, 0x000b)
print("Play again [Y/N]? ")
val a = readLine()!!.toLowerCase()
if (a.length > 0 && a[0] != 'y') {
nativeHeap.free(snk)
return
}
}
}

private fun createfield() {
memScoped {
val coord = alloc<COORD>().apply { X = 0; Y = 0 }
val c = alloc<DWORDVar>()
FillConsoleOutputCharacterW(console, 32, (HEI + 2) * 80, coord.readValue(), c.ptr)
FillConsoleOutputAttribute(console, 0x0000, (HEI + 2) * 80, coord.readValue(), c.ptr)
SetConsoleCursorPosition(console, coord.readValue())
}
for (x in 0 until WID * HEI) brd[x] = NUL
for (x in 0 until WID) {
brd[x + WID * (HEI - 1)] = '+'
brd[x] = '+'
}
for (y in 1 until HEI) {
brd[WID - 1 + WID * y] = '+'
brd[WID * y] = '+'
}
var xx: Int
var yy: Int
do {
xx = rand() % WID
yy = rand() % (HEI shr 1) + (HEI shr 1)
}
while (brd[xx + WID * yy] != NUL)
brd[xx + WID * yy] = '@'
tailIdx = 0
headIdx = 4
xx = 3
yy = 2
for (cc in tailIdx until headIdx) {
brd[xx + WID * yy] = '#'
snk[cc].X = (3 + cc).toShort()
snk[cc].Y = 2
}
head = snk[3]
dir = Dir.EAST
points = 0
}

private fun readKey() {
if ((GetAsyncKeyState(39).toInt() and 0x8000) != 0) dir = Dir.EAST
if ((GetAsyncKeyState(37).toInt() and 0x8000) != 0) dir = Dir.WEST
if ((GetAsyncKeyState(38).toInt() and 0x8000) != 0) dir = Dir.NORTH
if ((GetAsyncKeyState(40).toInt() and 0x8000) != 0) dir = Dir.SOUTH
}

private fun drawfield() {
memScoped {
val coord = alloc<COORD>()
var t = NUL
for (y in 0 until HEI) {
coord.Y = y.toShort()
for (x in 0 until WID) {
t = brd[x + WID * y]
if (t == NUL) continue
coord.X = x.toShort()
SetConsoleCursorPosition(console, coord.readValue())
if (coord.X == head.X && coord.Y == head.Y) {
SetConsoleTextAttribute(console, 0x002e)
print('O')
SetConsoleTextAttribute(console, 0x0000)
continue
}
when (t) {
'#' -> SetConsoleTextAttribute(console, 0x002a)
'+' -> SetConsoleTextAttribute(console, 0x0019)
'@' -> SetConsoleTextAttribute(console, 0x004c)
}
print(t)
SetConsoleTextAttribute(console, 0x0000)
}
}
print(t)
SetConsoleTextAttribute(console, 0x0007)
val c = alloc<COORD>().apply { X = 0; Y = HEI.toShort() }
SetConsoleCursorPosition(console, c.readValue())
print("Points: $points")
}
}

private fun moveSnake() {
when (dir) {
Dir.NORTH -> head.Y--
Dir.EAST -> head.X++
Dir.SOUTH -> head.Y++
Dir.WEST -> head.X--
}
val t = brd[head.X + WID * head.Y]
if (t != NUL && t != '@') {
alive = false
return
}
brd[head.X + WID * head.Y] = '#'
snk[headIdx].X = head.X
snk[headIdx].Y = head.Y
if (++headIdx >= MAX_LEN) headIdx = 0
if (t == '@') {
points++
var x: Int
var y: Int
do {
x = rand() % WID
y = rand() % (HEI shr 1) + (HEI shr 1)
}
while (brd[x + WID * y] != NUL)
brd[x + WID * y] = '@'
return
}
SetConsoleCursorPosition(console, snk[tailIdx].readValue())
print(' ')
brd[snk[tailIdx].X + WID * snk[tailIdx].Y] = NUL
if (++tailIdx >= MAX_LEN) tailIdx = 0
}
}

fun main(args: Array<String>) {
srand(time(null).toInt())
Snake().play()
}</lang>

{{output}}
<pre>
Similar to C++ entry
</pre>


=={{header|Java}}==
=={{header|Java}}==