@ -27,13 +27,13 @@ googleAnalytics = "" # Enable Google Analytics by entering your tracking id
@@ -27,13 +27,13 @@ googleAnalytics = "" # Enable Google Analytics by entering your tracking id
title: "Textris - Creating a terminal-based Tetris clone - Part 1: Pieces and playfield"
#date: 2019-11-26T01:42:18-07:00
title: "Terminal-based Tetris - Part 1: Procedural polyomino generation"
date: 2020-01-18T08:30:00-07:00
categories: [tutorial]
draft: true
aliases:
- /post/textris-1/
---
This is the first in a series of tutorials on creating a [terminal-based](https://en.wikipedia.org/wiki/Text-based_user_interface) [Tetris](https://en.wikipedia.org/wiki/Tetris) clone with [Go](https://golang.org).
This is the first part of a series of tutorials on creating a [terminal-based](https://en.wikipedia.org/wiki/Text-based_user_interface)
[Tetris](https://en.wikipedia.org/wiki/Tetris) clone with [Go](https://golang.org).
Game pieces (minos) are generated and added to a playfield (matrix).
For a complete implementation of a Tetris clone in Go, see [netris](https://git.sr.ht/~tslocum/netris).
## Disclaimer
# Disclaimer
Tetris is a registered trademark of the Tetris Holding, LLC.
Rocket Nine Labs is in no way affiliated with Tetris Holding, LLC.
## Contents
## Minos
* [Minos](#minos)
* [Data model](#data-model)
* [Generation](#generation)
* [Comparing and sorting](#comparing-and-sorting)
* [Generating new minos](#generating-new-minos)
* [Matrix](#matrix)
* [Data model](#data-model)
Game pieces are called "minos" because they are [polyominos](https://en.wikipedia.org/wiki/Polyomino).
This tutorial series will focus on the seven one-sided [terominos](https://en.wikipedia.org/wiki/Tetromino),
where each piece has four blocks.
# Minos
```
XX X X X XX XX
XXXX XX XXX XXX XXX XX XX
Game pieces are called "minos" because they are [polyominos](https://en.wikipedia.org/wiki/Polyomino).
This tutorial focuses on the seven one-sided [terominos](https://en.wikipedia.org/wiki/Tetromino), where each piece has four blocks.
I O T J L S Z
```
The number of blocks a mino has is also known as its rank.
Another transformation is applied not only to help identify duplicate minos, but also to retrieve their initial rotation, as [pieces should spawn flat-side down](https://tetris.wiki/Super_Rotation_System).
Another transformation is applied not only to help identify duplicate minos,
but also to retrieve their initial rotation, as [pieces should spawn flat-side down](https://tetris.wiki/Super_Rotation_System).
The flattest side is calculated and a flattened mino is returned.
Flatten calculates the flattest side of a mino and returns a flattened mino.
title: "Terminal-based Tetris - Part 2: The matrix"
#date: 2019-11-26T01:42:18-07:00
categories: [tutorial]
draft: true
aliases:
- /post/textris-2/
---
This is the second part of a series of tutorials on creating a [terminal-based](https://en.wikipedia.org/wiki/Text-based_user_interface) [Tetris](https://en.wikipedia.org/wiki/Tetris) clone with [Go](https://golang.org).
For a complete implementation of a Tetris clone in Go, see [netris](https://git.sr.ht/~tslocum/netris).
# Disclaimer
Tetris is a registered trademark of the Tetris Holding, LLC.
Rocket Nine Labs is in no way affiliated with Tetris Holding, LLC.
## Matrix
The matrix is typically 10 blocks wide and 20 blocks high.
### Matrix data model
A block is an integer representing the contents of a single X-Y coordinate on the matrix.
{{<highlightgo>}}
type Block int
const (
BlockNone Block = iota
BlockSolidBlue
BlockSolidCyan
BlockSolidRed
BlockSolidYellow
BlockSolidMagenta
BlockSolidGreen
BlockSolidOrange
)
{{</highlight>}}
The matrix will be stored as a slice of blocks.
The zero-value of Block is a blank space.
The matrix has a width, height and buffer height.
The buffer is additional space above the visible playfield.
{{<highlightgo>}}
type Matrix struct {
W int // Width
H in // Height
B int // Buffer height
M []Block // Contents
}
func NewMatrix(w int, h int, b int) *Matrix {
m := Matrix{
W: w,
H: h,
B: b,
M: make([]Block, w*(h+b)),
}
return &m
}
{{</highlight>}}
To retrieve the contents of a point, we calculate its index by multiplying the Y coordinate with the matrix width and adding the X coordinate.
{{<highlightgo>}}
func I(x int, y int, w int) int {
if x <0||x>= w || y <0{
log.Panicf("failed to retrieve index for %d,%d width %d: invalid coordinates", x, y, w)
}
return (y * w) + x
}
func (m *Matrix) Block(x int, y int) Block {
if y >= m.H+m.B {
log.Panicf("failed to retrieve block at %d,%d: invalid y coordinate", x, y)