Pencroff

Proj 2048

A few years ago Gabriele Cirulli developed a sliding puzzle where the goal is to grow tiles and get up to 2048. My β€œProj 2048” is about implementing several agents to play. Which should get tiles up to 4096 or maybe even 64536 (if it’s possible of course) πŸ˜‰.

As a start point, I implemented elementary clockwise and anticlockwise agents, I was surprised how easy they can get the tile with 256 scores. My first few games stuck on 128.

Let get to implementation details.

Technologies

Of course, Go-lang based. The Ebiten is the most popular and most advanced 2D game engine available for Go lang. The gg library helps a lot with 2D drawing and preparation sprites.

Architecture

Entity Component System (ECS) pattern.

What exactly is ESC let’s discuss it late. For now, let’s agree to use it as a pattern to separate data (component), processing logic (system), and entities group components under single roof.

ESC requires some kind of library that will manage components, entities, and execute systems. The project was made with mizu lib.

I used ESC for the first time and probably didn’t do the correct declaration of components.

I faced an issue to use pointers as a field type. To quickly solve it - wrapped by extra tier check code example below. Workaround highlighted.

It could be limitation of used ECS library (it based on reflection) or incorrect usage on my side πŸ˜€

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// Tile component
type TileProp struct {
	Value       int
	Position    image.Point
	EndPosition image.Point
	Speed       image.Point
	IsMoving    bool
	Removed     bool
	Sprite      *ebiten.Image
}

type TilePropWrap struct {
	Ptr *TileProp
}

// Tile entity
type Tile struct {
	component.TilePropWrap
}

Agent interface

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
type Agent interface {
	GetId() string
	GetName() string
	IsManual() bool
	GetGameId() int64
	GetGameSeed() int64

	MakeMove(step int, score int, noMove bool, valueList []int) common.Direction

	GameFinished(step int, score int, noMove bool, valueList []int, d common.Direction)

	LogStep(step int, score int, noMove bool, valueList []int, d common.Direction) error
}

The agent has to decide about next move base on current game state valueList and some other values such as noMove flag (true if was not possible to move by previous try, i.e. full board but collapsible vertically, but tried to move horizontally) or game step number.

The direction is just a string typed as “Direction”

1
2
3
4
5
6
7
8
9
type Direction string

const (
	NoDirection Direction = "no_direction"
	Up                    = "up"
	Right                 = "right"
	Down                  = "down"
	Left                  = "left"
)

Summary

Please try to play on the project page (WebAssembly) or check how far agents’ progress can be.