Skip to content

Commit

Permalink
base game with block
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuechlin committed Mar 12, 2024
0 parents commit 6e5c4a7
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 0 deletions.
73 changes: 73 additions & 0 deletions field.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"strings"
)

const W = 10
const H = 20

var COLORS = map[int]int{
0: 0,
1: 10,
2: 20,
3: 40,
4: 50,
}

type Field struct {
Curr Piece
Cells [W * H]int
}

type Piece struct {
Id int
X int
Y int
}

func idx(x int, y int) int {
return x + W*y
}

func (f *Field) CollisionDown() bool {
y := f.Curr.Y + 1
next := idx(f.Curr.X, y)
return y >= H || f.Cells[next] != 0
}
func (f *Field) CollisionLeft() bool {
x := f.Curr.X - 1
next := idx(x, f.Curr.Y)
return x < 0 || f.Cells[next] != 0
}
func (f *Field) CollisionRight() bool {
x := f.Curr.X + 1
next := idx(x, f.Curr.Y)
return x >= W || f.Cells[next] != 0
}

func (f *Field) String() []string {
lines := []string{}
lines = append(lines, "┌"+strings.Repeat("─", W*2)+"┐")
piece := idx(f.Curr.X, f.Curr.Y)
for y := 0; y < H; y++ {
value := "│"
for x := 0; x < W; x++ {
i := idx(x, y)
if i == piece {
value += block(COLORS[f.Curr.Id])
} else {
val := f.Cells[idx(x, y)]
if val == 0 {
value += empty()
} else {
value += block(COLORS[val])
}
}
}
value += "│"
lines = append(lines, value)
}
lines = append(lines, "└"+strings.Repeat("─", W*2)+"┘")
return lines
}
145 changes: 145 additions & 0 deletions game.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package main

import (
"fmt"
"math/rand"
"os"
"time"
)

type Game struct {
done *chan bool
ticker *time.Ticker
field Field
logs []string
}

func NewGame(done *chan bool) *Game {
game := Game{
done: done,
ticker: time.NewTicker(time.Second),
field: Field{
Curr: Piece{
Id: 1,
X: 0,
Y: 0,
},
},
}

go game.update()
go game.inputs()

return &game
}

func (g *Game) Draw() {
lines := g.field.String()
for i, line := range lines {
val := " " + line
if len(g.logs) > i {
val += " - " + g.logs[i]
}
fmt.Println(val)
}
}

func (g *Game) Redraw() {
clear_lines(H + 2)
g.Draw()
}

func (g *Game) update() {
for {
select {
case <-g.ticker.C:
g.moveDown()
}
}
}

func (g *Game) log(msg string) {
if len(g.logs) >= 10 {
g.logs = append(g.logs[1:], msg)
} else {
g.logs = append(g.logs, msg)
}
}

// ESC [
// 27 91 __
// - up 65
// - down 66
// - right 67
// - left 68
func (g *Game) inputs() {
var b []byte = make([]byte, 3)
for {
os.Stdin.Read(b)
if b[0] == 27 && b[1] == 91 {
switch b[2] {
case 65:
fmt.Println("up")
case 66:
g.moveDown()
case 67:
g.moveRight()
case 68:
g.moveLeft()
}
}
}
}

func (g *Game) moveDown() {
if g.field.CollisionDown() {
// place block
i := idx(g.field.Curr.X, g.field.Curr.Y)
g.field.Cells[i] = g.field.Curr.Id
// Spawn next block
g.Spawn()
} else {
// move
g.log("move down")
g.field.Curr.Y += 1
g.Redraw()
}
}

func (g *Game) moveLeft() {
if g.field.CollisionLeft() {
return
}
g.log("move left")
g.field.Curr.X -= 1
g.Redraw()
}

func (g *Game) moveRight() {
if g.field.CollisionRight() {
return
}
g.log("move right")
g.field.Curr.X += 1
g.Redraw()
}

func (g *Game) Spawn() {
p := Piece{
X: W / 2,
Y: 0,
Id: 1 + rand.Intn(4),
}
i := idx(p.X, p.Y)

if g.field.Cells[i] != 0 {
// end game
fmt.Println("gg")
*g.done <- true
return
}

g.log(fmt.Sprintf("span %d at %d, %d", p.Id, p.X, p.Y))
g.field.Curr = p
g.Redraw()
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/kuechlin/gotris

go 1.21.7
27 changes: 27 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"fmt"
"os/exec"
"time"
)

var ticker *time.Ticker

func main() {
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
exec.Command("stty", "-F", "/dev/tty", "-echo").Run()
exec.Command("tput", "civis")

done := make(chan bool)
game := NewGame(&done)
fmt.Println("> gotris")
game.Draw()

for {
select {
case <-done:
return
}
}
}
23 changes: 23 additions & 0 deletions ui.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"fmt"
"strings"
)

const clear_line = "\033[1A\033[2K"

func clear_lines(lines int) {
fmt.Print(strings.Repeat(clear_line, lines))
}

func colored(color int, value string) string {
return fmt.Sprintf("\033[38;5;%dm%s\033[0m", color, value)
}

func block(color int) string {
return colored(color, "██")
}
func empty() string {
return " "
}

0 comments on commit 6e5c4a7

Please sign in to comment.