2009-10-15 12:04:33 -06:00
|
|
|
// games/4s - a tetris clone
|
|
|
|
//
|
|
|
|
// Derived from Plan 9's /sys/src/games/xs.c
|
|
|
|
// http://plan9.bell-labs.com/sources/plan9/sys/src/games/xs.c
|
|
|
|
//
|
|
|
|
// Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights Reserved.
|
|
|
|
// Portions Copyright 2009 The Go Authors. All Rights Reserved.
|
|
|
|
// Distributed under the terms of the Lucent Public License Version 1.02
|
|
|
|
// See http://plan9.bell-labs.com/plan9/license.html
|
|
|
|
|
|
|
|
/*
|
|
|
|
* engine for 4s, 5s, etc
|
|
|
|
*/
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2009-12-15 16:27:16 -07:00
|
|
|
"exp/draw"
|
|
|
|
"image"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"rand"
|
|
|
|
"time"
|
2009-10-15 12:04:33 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
Cursor whitearrow = {
|
|
|
|
{0, 0},
|
|
|
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
|
|
|
|
0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC,
|
|
|
|
0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
|
|
|
|
0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, },
|
|
|
|
{0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C,
|
|
|
|
0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C,
|
|
|
|
0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C,
|
|
|
|
0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
const (
|
2009-12-15 16:27:16 -07:00
|
|
|
CNone = 0
|
|
|
|
CBounds = 1
|
|
|
|
CPiece = 2
|
|
|
|
NX = 10
|
|
|
|
NY = 20
|
2009-10-15 12:04:33 -06:00
|
|
|
|
2009-12-15 16:27:16 -07:00
|
|
|
NCOL = 10
|
2009-10-15 12:04:33 -06:00
|
|
|
|
2009-12-15 16:27:16 -07:00
|
|
|
MAXN = 5
|
2009-10-15 12:04:33 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2009-12-15 16:27:16 -07:00
|
|
|
N int
|
|
|
|
display draw.Context
|
|
|
|
screen draw.Image
|
|
|
|
screenr draw.Rectangle
|
|
|
|
board [NY][NX]byte
|
|
|
|
rboard draw.Rectangle
|
|
|
|
pscore draw.Point
|
|
|
|
scoresz draw.Point
|
|
|
|
pcsz = 32
|
|
|
|
pos draw.Point
|
|
|
|
bbr, bb2r draw.Rectangle
|
|
|
|
bb, bbmask, bb2, bb2mask *image.RGBA
|
|
|
|
whitemask image.Image
|
|
|
|
br, br2 draw.Rectangle
|
|
|
|
points int
|
|
|
|
dt int
|
|
|
|
DY int
|
|
|
|
DMOUSE int
|
|
|
|
lastmx int
|
|
|
|
mouse draw.Mouse
|
|
|
|
newscreen bool
|
|
|
|
timerc <-chan int64
|
|
|
|
suspc chan bool
|
|
|
|
mousec chan draw.Mouse
|
|
|
|
resizec <-chan bool
|
|
|
|
kbdc chan int
|
|
|
|
suspended bool
|
|
|
|
tsleep int
|
|
|
|
piece *Piece
|
|
|
|
pieces []Piece
|
2009-10-15 12:04:33 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
type Piece struct {
|
2009-12-15 16:27:16 -07:00
|
|
|
rot int
|
|
|
|
tx int
|
|
|
|
sz draw.Point
|
|
|
|
d []draw.Point
|
|
|
|
left *Piece
|
|
|
|
right *Piece
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
var txbits = [NCOL][32]byte{
|
2009-11-05 15:43:03 -07:00
|
|
|
[32]byte{0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
|
|
|
|
0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
|
|
|
|
0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
|
|
|
|
0xDD, 0xDD, 0xFF, 0xFF, 0x77, 0x77, 0xFF, 0xFF,
|
|
|
|
},
|
|
|
|
[32]byte{0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
|
|
|
|
0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
|
|
|
|
0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
|
|
|
|
0xDD, 0xDD, 0x77, 0x77, 0xDD, 0xDD, 0x77, 0x77,
|
|
|
|
},
|
|
|
|
[32]byte{0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
},
|
|
|
|
[32]byte{0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
0xAA, 0xAA, 0x55, 0x55, 0xAA, 0xAA, 0x55, 0x55,
|
|
|
|
},
|
|
|
|
[32]byte{0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
|
|
|
|
0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
|
|
|
|
0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
|
|
|
|
0x22, 0x22, 0x88, 0x88, 0x22, 0x22, 0x88, 0x88,
|
|
|
|
},
|
|
|
|
[32]byte{0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
|
|
|
|
0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
|
|
|
|
0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
|
|
|
|
0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,
|
|
|
|
},
|
|
|
|
[32]byte{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
},
|
|
|
|
[32]byte{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
},
|
|
|
|
[32]byte{0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
|
|
},
|
|
|
|
[32]byte{0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
|
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
|
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
|
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0x33, 0x33, 0x33, 0x33,
|
|
|
|
},
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
var txpix = [NCOL]draw.Color{
|
2010-02-25 14:47:16 -07:00
|
|
|
draw.Yellow, /* yellow */
|
|
|
|
draw.Cyan, /* cyan */
|
|
|
|
draw.Green, /* lime green */
|
|
|
|
draw.GreyBlue, /* slate */
|
|
|
|
draw.Red, /* red */
|
|
|
|
draw.GreyGreen, /* olive green */
|
|
|
|
draw.Blue, /* blue */
|
2009-12-15 16:27:16 -07:00
|
|
|
draw.Color(0xFF55AAFF), /* pink */
|
|
|
|
draw.Color(0xFFAAFFFF), /* lavender */
|
|
|
|
draw.Color(0xBB005DFF), /* maroon */
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func movemouse() int {
|
|
|
|
//mouse.draw.Point = draw.Pt(rboard.Min.X + rboard.Dx()/2, rboard.Min.Y + rboard.Dy()/2);
|
|
|
|
//moveto(mousectl, mouse.Xy);
|
2009-11-09 13:07:39 -07:00
|
|
|
return mouse.X
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func warp(p draw.Point, x int) int {
|
|
|
|
if !suspended && piece != nil {
|
2009-12-15 16:27:16 -07:00
|
|
|
x = pos.X + piece.sz.X*pcsz/2
|
2009-10-15 12:04:33 -06:00
|
|
|
if p.Y < rboard.Min.Y {
|
2009-11-09 13:07:39 -07:00
|
|
|
p.Y = rboard.Min.Y
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if p.Y >= rboard.Max.Y {
|
2009-11-09 13:07:39 -07:00
|
|
|
p.Y = rboard.Max.Y - 1
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
//moveto(mousectl, draw.Pt(x, p.Y));
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return x
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func initPieces() {
|
|
|
|
for i := range pieces {
|
2009-12-15 16:27:16 -07:00
|
|
|
p := &pieces[i]
|
2009-10-15 12:04:33 -06:00
|
|
|
if p.rot == 3 {
|
2009-11-09 13:07:39 -07:00
|
|
|
p.right = &pieces[i-3]
|
2009-10-15 12:04:33 -06:00
|
|
|
} else {
|
2009-11-09 13:07:39 -07:00
|
|
|
p.right = &pieces[i+1]
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if p.rot == 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
p.left = &pieces[i+3]
|
2009-10-15 12:04:33 -06:00
|
|
|
} else {
|
2009-11-09 13:07:39 -07:00
|
|
|
p.left = &pieces[i-1]
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func collide(pt draw.Point, p *Piece) bool {
|
2009-12-15 16:27:16 -07:00
|
|
|
pt.X = (pt.X - rboard.Min.X) / pcsz
|
|
|
|
pt.Y = (pt.Y - rboard.Min.Y) / pcsz
|
2009-10-15 12:04:33 -06:00
|
|
|
for _, q := range p.d {
|
2009-12-15 16:27:16 -07:00
|
|
|
pt.X += q.X
|
|
|
|
pt.Y += q.Y
|
2009-11-05 15:43:03 -07:00
|
|
|
if pt.X < 0 || pt.X >= NX || pt.Y < 0 || pt.Y >= NY {
|
2009-12-15 16:27:16 -07:00
|
|
|
return true
|
|
|
|
continue
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if board[pt.Y][pt.X] != 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return true
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return false
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func collider(pt, pmax draw.Point) bool {
|
2009-12-15 16:27:16 -07:00
|
|
|
pi := (pt.X - rboard.Min.X) / pcsz
|
|
|
|
pj := (pt.Y - rboard.Min.Y) / pcsz
|
|
|
|
n := pmax.X / pcsz
|
|
|
|
m := pmax.Y/pcsz + 1
|
2009-10-15 12:04:33 -06:00
|
|
|
for i := pi; i < pi+n && i < NX; i++ {
|
|
|
|
for j := pj; j < pj+m && j < NY; j++ {
|
|
|
|
if board[j][i] != 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return true
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return false
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func setpiece(p *Piece) {
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(bb, bbr, draw.White, draw.ZP)
|
|
|
|
draw.Draw(bbmask, bbr, draw.Transparent, draw.ZP)
|
2009-12-15 16:27:16 -07:00
|
|
|
br = draw.Rect(0, 0, 0, 0)
|
|
|
|
br2 = br
|
|
|
|
piece = p
|
2009-10-15 12:04:33 -06:00
|
|
|
if p == nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
var op draw.Point
|
|
|
|
var r draw.Rectangle
|
|
|
|
r.Min = bbr.Min
|
2009-10-15 12:04:33 -06:00
|
|
|
for i, pt := range p.d {
|
2009-12-15 16:27:16 -07:00
|
|
|
r.Min.X += pt.X * pcsz
|
|
|
|
r.Min.Y += pt.Y * pcsz
|
|
|
|
r.Max.X = r.Min.X + pcsz
|
|
|
|
r.Max.Y = r.Min.Y + pcsz
|
2009-10-15 12:04:33 -06:00
|
|
|
if i == 0 {
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(bb, r, draw.Black, draw.ZP)
|
|
|
|
draw.Draw(bb, r.Inset(1), txpix[piece.tx], draw.ZP)
|
|
|
|
draw.Draw(bbmask, r, draw.Opaque, draw.ZP)
|
2009-12-15 16:27:16 -07:00
|
|
|
op = r.Min
|
2009-11-05 15:43:03 -07:00
|
|
|
} else {
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(bb, r, bb, op)
|
|
|
|
draw.Draw(bbmask, r, bbmask, op)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if br.Max.X < r.Max.X {
|
2009-11-09 13:07:39 -07:00
|
|
|
br.Max.X = r.Max.X
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if br.Max.Y < r.Max.Y {
|
2009-11-09 13:07:39 -07:00
|
|
|
br.Max.Y = r.Max.Y
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
br.Max = br.Max.Sub(bbr.Min)
|
|
|
|
delta := draw.Pt(0, DY)
|
|
|
|
br2.Max = br.Max.Add(delta)
|
|
|
|
r = br.Add(bb2r.Min)
|
|
|
|
r2 := br2.Add(bb2r.Min)
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(bb2, r2, draw.White, draw.ZP)
|
|
|
|
draw.Draw(bb2, r.Add(delta), bb, bbr.Min)
|
|
|
|
draw.Draw(bb2mask, r2, draw.Transparent, draw.ZP)
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(bb2mask, r, draw.Opaque, bbr.Min, bbmask, draw.ZP, draw.Over)
|
|
|
|
draw.DrawMask(bb2mask, r.Add(delta), draw.Opaque, bbr.Min, bbmask, draw.ZP, draw.Over)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func drawpiece() {
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, br.Add(pos), bb, bbr.Min, bbmask, draw.ZP, draw.Over)
|
2009-10-15 12:04:33 -06:00
|
|
|
if suspended {
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, br.Add(pos), draw.White, draw.ZP, whitemask, draw.ZP, draw.Over)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func undrawpiece() {
|
2009-12-15 16:27:16 -07:00
|
|
|
var mask image.Image
|
2009-10-15 12:04:33 -06:00
|
|
|
if collider(pos, br.Max) {
|
2009-11-09 13:07:39 -07:00
|
|
|
mask = bbmask
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, br.Add(pos), draw.White, bbr.Min, mask, bbr.Min, draw.Over)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func rest() {
|
2009-12-15 16:27:16 -07:00
|
|
|
pt := pos.Sub(rboard.Min).Div(pcsz)
|
2009-10-15 12:04:33 -06:00
|
|
|
for _, p := range piece.d {
|
2009-12-15 16:27:16 -07:00
|
|
|
pt.X += p.X
|
|
|
|
pt.Y += p.Y
|
|
|
|
board[pt.Y][pt.X] = byte(piece.tx + 16)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func canfit(p *Piece) bool {
|
2009-12-15 16:27:16 -07:00
|
|
|
var dx = [...]int{0, -1, 1, -2, 2, -3, 3, 4, -4}
|
|
|
|
j := N + 1
|
2009-10-15 12:04:33 -06:00
|
|
|
if j >= 4 {
|
2009-12-15 16:27:16 -07:00
|
|
|
j = p.sz.X
|
2009-11-05 15:43:03 -07:00
|
|
|
if j < p.sz.Y {
|
2009-11-09 13:07:39 -07:00
|
|
|
j = p.sz.Y
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
j = 2*j - 1
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-11-05 15:43:03 -07:00
|
|
|
for i := 0; i < j; i++ {
|
2009-12-15 16:27:16 -07:00
|
|
|
var z draw.Point
|
|
|
|
z.X = pos.X + dx[i]*pcsz
|
|
|
|
z.Y = pos.Y
|
2009-10-15 12:04:33 -06:00
|
|
|
if !collide(z, p) {
|
2009-12-15 16:27:16 -07:00
|
|
|
z.Y = pos.Y + pcsz - 1
|
2009-10-15 12:04:33 -06:00
|
|
|
if !collide(z, p) {
|
2009-12-15 16:27:16 -07:00
|
|
|
undrawpiece()
|
|
|
|
pos.X = z.X
|
|
|
|
return true
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
return false
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func score(p int) {
|
2009-11-09 13:07:39 -07:00
|
|
|
points += p
|
2009-11-05 15:43:03 -07:00
|
|
|
// snprint(buf, sizeof(buf), "%.6ld", points);
|
2010-02-04 03:21:32 -07:00
|
|
|
// draw.Draw(screen, draw.Rpt(pscore, pscore.Add(scoresz)), draw.White, draw.ZP);
|
2009-11-05 15:43:03 -07:00
|
|
|
// string(screen, pscore, draw.Black, draw.ZP, font, buf);
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func drawsq(b draw.Image, p draw.Point, ptx int) {
|
2009-12-15 16:27:16 -07:00
|
|
|
var r draw.Rectangle
|
|
|
|
r.Min = p
|
|
|
|
r.Max.X = r.Min.X + pcsz
|
|
|
|
r.Max.Y = r.Min.Y + pcsz
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(b, r, draw.Black, draw.ZP)
|
|
|
|
draw.Draw(b, r.Inset(1), txpix[ptx], draw.ZP)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func drawboard() {
|
2009-12-15 16:27:16 -07:00
|
|
|
draw.Border(screen, rboard.Inset(-2), 2, draw.Black, draw.ZP)
|
2009-11-09 22:13:17 -07:00
|
|
|
draw.Draw(screen, draw.Rect(rboard.Min.X, rboard.Min.Y-2, rboard.Max.X, rboard.Min.Y),
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.White, draw.ZP)
|
2009-11-05 15:43:03 -07:00
|
|
|
for i := 0; i < NY; i++ {
|
|
|
|
for j := 0; j < NX; j++ {
|
2009-10-15 12:04:33 -06:00
|
|
|
if board[i][j] != 0 {
|
2009-11-09 22:13:17 -07:00
|
|
|
drawsq(screen, draw.Pt(rboard.Min.X+j*pcsz, rboard.Min.Y+i*pcsz), int(board[i][j]-16))
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
score(0)
|
2009-10-15 12:04:33 -06:00
|
|
|
if suspended {
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, screenr, draw.White, draw.ZP, whitemask, draw.ZP, draw.Over)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func choosepiece() {
|
|
|
|
for {
|
2009-12-15 16:27:16 -07:00
|
|
|
i := rand.Intn(len(pieces))
|
|
|
|
setpiece(&pieces[i])
|
|
|
|
pos = rboard.Min
|
|
|
|
pos.X += rand.Intn(NX) * pcsz
|
2009-11-09 22:13:17 -07:00
|
|
|
if !collide(draw.Pt(pos.X, pos.Y+pcsz-DY), piece) {
|
2009-11-09 13:07:39 -07:00
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
drawpiece()
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func movepiece() bool {
|
2009-12-15 16:27:16 -07:00
|
|
|
var mask image.Image
|
2009-11-09 22:13:17 -07:00
|
|
|
if collide(draw.Pt(pos.X, pos.Y+pcsz), piece) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return false
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if collider(pos, br2.Max) {
|
2009-11-09 13:07:39 -07:00
|
|
|
mask = bb2mask
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, br2.Add(pos), bb2, bb2r.Min, mask, bb2r.Min, draw.Over)
|
2009-12-15 16:27:16 -07:00
|
|
|
pos.Y += DY
|
|
|
|
display.FlushImage()
|
|
|
|
return true
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func suspend(s bool) {
|
2009-12-15 16:27:16 -07:00
|
|
|
suspended = s
|
2009-10-15 12:04:33 -06:00
|
|
|
/*
|
2009-11-05 15:43:03 -07:00
|
|
|
if suspended {
|
|
|
|
setcursor(mousectl, &whitearrow);
|
|
|
|
} else {
|
|
|
|
setcursor(mousectl, nil);
|
|
|
|
}
|
2009-10-15 12:04:33 -06:00
|
|
|
*/
|
|
|
|
if !suspended {
|
2009-11-09 13:07:39 -07:00
|
|
|
drawpiece()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
drawboard()
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func pause(t int) {
|
2009-12-15 16:27:16 -07:00
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case s := <-suspc:
|
|
|
|
if !suspended && s {
|
2009-11-09 13:07:39 -07:00
|
|
|
suspend(true)
|
2009-10-15 12:04:33 -06:00
|
|
|
} else if suspended && !s {
|
2009-12-15 16:27:16 -07:00
|
|
|
suspend(false)
|
|
|
|
lastmx = warp(mouse.Point, lastmx)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
case <-timerc:
|
|
|
|
if suspended {
|
2009-11-09 13:07:39 -07:00
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
t -= tsleep
|
2009-10-15 12:04:33 -06:00
|
|
|
if t < 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
case <-resizec:
|
|
|
|
//redraw(true);
|
|
|
|
case mouse = <-mousec:
|
|
|
|
case <-kbdc:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func horiz() bool {
|
2009-12-15 16:27:16 -07:00
|
|
|
var lev [MAXN]int
|
|
|
|
h := 0
|
2009-11-05 15:43:03 -07:00
|
|
|
for i := 0; i < NY; i++ {
|
|
|
|
for j := 0; board[i][j] != 0; j++ {
|
2009-10-15 12:04:33 -06:00
|
|
|
if j == NX-1 {
|
2009-12-15 16:27:16 -07:00
|
|
|
lev[h] = i
|
|
|
|
h++
|
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if h == 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
return false
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
r := rboard
|
|
|
|
newscreen = false
|
2009-11-05 15:43:03 -07:00
|
|
|
for j := 0; j < h; j++ {
|
2009-12-15 16:27:16 -07:00
|
|
|
r.Min.Y = rboard.Min.Y + lev[j]*pcsz
|
|
|
|
r.Max.Y = r.Min.Y + pcsz
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, r, draw.White, draw.ZP, whitemask, draw.ZP, draw.Over)
|
2009-12-15 16:27:16 -07:00
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
PlaySound(whoosh)
|
2009-11-05 15:43:03 -07:00
|
|
|
for i := 0; i < 3; i++ {
|
2009-12-15 16:27:16 -07:00
|
|
|
pause(250)
|
2009-10-15 12:04:33 -06:00
|
|
|
if newscreen {
|
2009-12-15 16:27:16 -07:00
|
|
|
drawboard()
|
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-11-05 15:43:03 -07:00
|
|
|
for j := 0; j < h; j++ {
|
2009-12-15 16:27:16 -07:00
|
|
|
r.Min.Y = rboard.Min.Y + lev[j]*pcsz
|
|
|
|
r.Max.Y = r.Min.Y + pcsz
|
2010-02-16 20:34:51 -07:00
|
|
|
draw.DrawMask(screen, r, draw.White, draw.ZP, whitemask, draw.ZP, draw.Over)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
r = rboard
|
2009-11-05 15:43:03 -07:00
|
|
|
for j := 0; j < h; j++ {
|
2009-12-15 16:27:16 -07:00
|
|
|
i := NY - lev[j] - 1
|
|
|
|
score(250 + 10*i*i)
|
|
|
|
r.Min.Y = rboard.Min.Y
|
|
|
|
r.Max.Y = rboard.Min.Y + lev[j]*pcsz
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(screen, r.Add(draw.Pt(0, pcsz)), screen, r.Min)
|
2009-12-15 16:27:16 -07:00
|
|
|
r.Max.Y = rboard.Min.Y + pcsz
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(screen, r, draw.White, draw.ZP)
|
2009-11-09 22:13:17 -07:00
|
|
|
for k := lev[j] - 1; k >= 0; k-- {
|
2009-11-09 13:07:39 -07:00
|
|
|
board[k+1] = board[k]
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
board[0] = [NX]byte{}
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
display.FlushImage()
|
|
|
|
return true
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func mright() {
|
2009-11-09 22:13:17 -07:00
|
|
|
if !collide(draw.Pt(pos.X+pcsz, pos.Y), piece) &&
|
|
|
|
!collide(draw.Pt(pos.X+pcsz, pos.Y+pcsz-DY), piece) {
|
2009-12-15 16:27:16 -07:00
|
|
|
undrawpiece()
|
|
|
|
pos.X += pcsz
|
|
|
|
drawpiece()
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func mleft() {
|
2009-11-09 22:13:17 -07:00
|
|
|
if !collide(draw.Pt(pos.X-pcsz, pos.Y), piece) &&
|
|
|
|
!collide(draw.Pt(pos.X-pcsz, pos.Y+pcsz-DY), piece) {
|
2009-12-15 16:27:16 -07:00
|
|
|
undrawpiece()
|
|
|
|
pos.X -= pcsz
|
|
|
|
drawpiece()
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func rright() {
|
|
|
|
if canfit(piece.right) {
|
2009-12-15 16:27:16 -07:00
|
|
|
setpiece(piece.right)
|
|
|
|
drawpiece()
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func rleft() {
|
|
|
|
if canfit(piece.left) {
|
2009-12-15 16:27:16 -07:00
|
|
|
setpiece(piece.left)
|
|
|
|
drawpiece()
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var fusst = 0
|
|
|
|
|
|
|
|
func drop(f bool) bool {
|
|
|
|
if f {
|
2009-12-15 16:27:16 -07:00
|
|
|
score(5 * (rboard.Max.Y - pos.Y) / pcsz)
|
2009-10-15 12:04:33 -06:00
|
|
|
for movepiece() {
|
|
|
|
}
|
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
fusst = 0
|
|
|
|
rest()
|
2009-11-05 15:43:03 -07:00
|
|
|
if pos.Y == rboard.Min.Y && !horiz() {
|
2009-11-09 13:07:39 -07:00
|
|
|
return true
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
horiz()
|
|
|
|
setpiece(nil)
|
|
|
|
pause(1500)
|
|
|
|
choosepiece()
|
|
|
|
lastmx = warp(mouse.Point, lastmx)
|
|
|
|
return false
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func play() {
|
2009-12-15 16:27:16 -07:00
|
|
|
var om draw.Mouse
|
|
|
|
dt = 64
|
|
|
|
lastmx = -1
|
|
|
|
lastmx = movemouse()
|
|
|
|
choosepiece()
|
|
|
|
lastmx = warp(mouse.Point, lastmx)
|
2009-10-15 12:04:33 -06:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case mouse = <-mousec:
|
2009-11-05 15:43:03 -07:00
|
|
|
if suspended {
|
2009-12-15 16:27:16 -07:00
|
|
|
om = mouse
|
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if lastmx < 0 {
|
2009-11-09 13:07:39 -07:00
|
|
|
lastmx = mouse.X
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if mouse.X > lastmx+DMOUSE {
|
2009-12-15 16:27:16 -07:00
|
|
|
mright()
|
|
|
|
lastmx = mouse.X
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
if mouse.X < lastmx-DMOUSE {
|
2009-12-15 16:27:16 -07:00
|
|
|
mleft()
|
|
|
|
lastmx = mouse.X
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-11-09 22:13:17 -07:00
|
|
|
if mouse.Buttons&^om.Buttons&1 == 1 {
|
2009-11-09 13:07:39 -07:00
|
|
|
rleft()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-11-09 22:13:17 -07:00
|
|
|
if mouse.Buttons&^om.Buttons&2 == 2 {
|
2009-10-15 12:04:33 -06:00
|
|
|
if drop(true) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
2009-11-09 22:13:17 -07:00
|
|
|
if mouse.Buttons&^om.Buttons&4 == 4 {
|
2009-11-09 13:07:39 -07:00
|
|
|
rright()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
om = mouse
|
2009-10-15 12:04:33 -06:00
|
|
|
|
|
|
|
case s := <-suspc:
|
|
|
|
if !suspended && s {
|
2009-11-09 13:07:39 -07:00
|
|
|
suspend(true)
|
2009-10-15 12:04:33 -06:00
|
|
|
} else if suspended && !s {
|
2009-12-15 16:27:16 -07:00
|
|
|
suspend(false)
|
|
|
|
lastmx = warp(mouse.Point, lastmx)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
case <-resizec:
|
|
|
|
//redraw(true);
|
|
|
|
|
|
|
|
case r := <-kbdc:
|
|
|
|
if suspended {
|
2009-11-09 13:07:39 -07:00
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-11-05 15:43:03 -07:00
|
|
|
switch r {
|
2009-10-15 12:04:33 -06:00
|
|
|
case 'f', ';':
|
2009-11-09 13:07:39 -07:00
|
|
|
mright()
|
2009-10-15 12:04:33 -06:00
|
|
|
case 'a', 'j':
|
2009-11-09 13:07:39 -07:00
|
|
|
mleft()
|
2009-10-15 12:04:33 -06:00
|
|
|
case 'd', 'l':
|
2009-11-09 13:07:39 -07:00
|
|
|
rright()
|
2009-10-15 12:04:33 -06:00
|
|
|
case 's', 'k':
|
2009-11-09 13:07:39 -07:00
|
|
|
rleft()
|
2009-10-15 12:04:33 -06:00
|
|
|
case ' ':
|
|
|
|
if drop(true) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
case <-timerc:
|
|
|
|
if suspended {
|
2009-11-09 13:07:39 -07:00
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
dt -= tsleep
|
2009-10-15 12:04:33 -06:00
|
|
|
if dt < 0 {
|
2009-12-15 16:27:16 -07:00
|
|
|
i := 1
|
|
|
|
dt = 16 * (points + rand.Intn(10000) - 5000) / 10000
|
2009-10-15 12:04:33 -06:00
|
|
|
if dt >= 32 {
|
2009-12-15 16:27:16 -07:00
|
|
|
i += (dt - 32) / 16
|
|
|
|
dt = 32
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
dt = 52 - dt
|
2009-10-15 12:04:33 -06:00
|
|
|
for ; i > 0; i-- {
|
|
|
|
if movepiece() {
|
2009-11-09 13:07:39 -07:00
|
|
|
continue
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
fusst++
|
2009-10-15 12:04:33 -06:00
|
|
|
if fusst == 40 {
|
|
|
|
if drop(false) {
|
2009-11-09 13:07:39 -07:00
|
|
|
return
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func suspproc() {
|
2009-12-15 16:27:16 -07:00
|
|
|
mc := display.MouseChan()
|
|
|
|
kc := display.KeyboardChan()
|
2009-10-15 12:04:33 -06:00
|
|
|
|
2009-12-15 16:27:16 -07:00
|
|
|
s := false
|
2009-10-15 12:04:33 -06:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case mouse = <-mc:
|
2009-11-09 13:07:39 -07:00
|
|
|
mousec <- mouse
|
2009-10-15 12:04:33 -06:00
|
|
|
case r := <-kc:
|
|
|
|
switch r {
|
|
|
|
case 'q', 'Q', 0x04, 0x7F:
|
2009-11-09 13:07:39 -07:00
|
|
|
os.Exit(0)
|
2009-10-15 12:04:33 -06:00
|
|
|
default:
|
|
|
|
if s {
|
2009-12-15 16:27:16 -07:00
|
|
|
s = false
|
|
|
|
suspc <- s
|
|
|
|
break
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
switch r {
|
|
|
|
case 'z', 'Z', 'p', 'P', 0x1B:
|
2009-12-15 16:27:16 -07:00
|
|
|
s = true
|
|
|
|
suspc <- s
|
2009-10-15 12:04:33 -06:00
|
|
|
default:
|
2009-11-09 13:07:39 -07:00
|
|
|
kbdc <- r
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func redraw(new bool) {
|
2009-11-05 15:43:03 -07:00
|
|
|
// if new && getwindow(display, Refmesg) < 0 {
|
|
|
|
// sysfatal("can't reattach to window");
|
|
|
|
// }
|
2009-12-15 16:27:16 -07:00
|
|
|
r := draw.Rect(0, 0, screen.Width(), screen.Height())
|
|
|
|
pos.X = (pos.X - rboard.Min.X) / pcsz
|
|
|
|
pos.Y = (pos.Y - rboard.Min.Y) / pcsz
|
|
|
|
dx := r.Max.X - r.Min.X
|
|
|
|
dy := r.Max.Y - r.Min.Y - 2*32
|
|
|
|
DY = dx / NX
|
2009-11-05 15:43:03 -07:00
|
|
|
if DY > dy/NY {
|
2009-11-09 22:13:17 -07:00
|
|
|
DY = dy / NY
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
DY /= 8
|
2009-10-15 12:04:33 -06:00
|
|
|
if DY > 4 {
|
2009-11-09 13:07:39 -07:00
|
|
|
DY = 4
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
pcsz = DY * 8
|
|
|
|
DMOUSE = pcsz / 3
|
2009-10-15 12:04:33 -06:00
|
|
|
if pcsz < 8 {
|
2009-11-09 13:07:39 -07:00
|
|
|
log.Exitf("screen too small: %d", pcsz)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
rboard = screenr
|
|
|
|
rboard.Min.X += (dx - pcsz*NX) / 2
|
|
|
|
rboard.Min.Y += (dy-pcsz*NY)/2 + 32
|
|
|
|
rboard.Max.X = rboard.Min.X + NX*pcsz
|
|
|
|
rboard.Max.Y = rboard.Min.Y + NY*pcsz
|
|
|
|
pscore.X = rboard.Min.X + 8
|
|
|
|
pscore.Y = rboard.Min.Y - 32
|
2009-11-05 15:43:03 -07:00
|
|
|
// scoresz = stringsize(font, "000000");
|
2009-12-15 16:27:16 -07:00
|
|
|
pos.X = pos.X*pcsz + rboard.Min.X
|
|
|
|
pos.Y = pos.Y*pcsz + rboard.Min.Y
|
|
|
|
bbr = draw.Rect(0, 0, N*pcsz, N*pcsz)
|
|
|
|
bb = image.NewRGBA(bbr.Max.X, bbr.Max.Y)
|
|
|
|
bbmask = image.NewRGBA(bbr.Max.X, bbr.Max.Y) // actually just a bitmap
|
|
|
|
bb2r = draw.Rect(0, 0, N*pcsz, N*pcsz+DY)
|
|
|
|
bb2 = image.NewRGBA(bb2r.Dx(), bb2r.Dy())
|
|
|
|
bb2mask = image.NewRGBA(bb2r.Dx(), bb2r.Dy()) // actually just a bitmap
|
2010-02-04 03:21:32 -07:00
|
|
|
draw.Draw(screen, screenr, draw.White, draw.ZP)
|
2009-12-15 16:27:16 -07:00
|
|
|
drawboard()
|
|
|
|
setpiece(piece)
|
2009-10-15 12:04:33 -06:00
|
|
|
if piece != nil {
|
2009-11-09 13:07:39 -07:00
|
|
|
drawpiece()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
2009-12-15 16:27:16 -07:00
|
|
|
lastmx = movemouse()
|
|
|
|
newscreen = true
|
|
|
|
display.FlushImage()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func quitter(c <-chan bool) {
|
2009-12-15 16:27:16 -07:00
|
|
|
<-c
|
|
|
|
os.Exit(0)
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func Play(pp []Piece, ctxt draw.Context) {
|
2009-12-15 16:27:16 -07:00
|
|
|
display = ctxt
|
|
|
|
screen = ctxt.Screen()
|
|
|
|
screenr = draw.Rect(0, 0, screen.Width(), screen.Height())
|
|
|
|
pieces = pp
|
|
|
|
N = len(pieces[0].d)
|
|
|
|
initPieces()
|
|
|
|
rand.Seed(int64(time.Nanoseconds() % (1e9 - 1)))
|
|
|
|
whitemask = draw.White.SetAlpha(0x7F)
|
|
|
|
tsleep = 50
|
|
|
|
timerc = time.Tick(int64(tsleep/2) * 1e6)
|
|
|
|
suspc = make(chan bool)
|
|
|
|
mousec = make(chan draw.Mouse)
|
|
|
|
resizec = ctxt.ResizeChan()
|
|
|
|
kbdc = make(chan int)
|
|
|
|
go quitter(ctxt.QuitChan())
|
|
|
|
go suspproc()
|
|
|
|
points = 0
|
|
|
|
redraw(false)
|
|
|
|
play()
|
2009-10-15 12:04:33 -06:00
|
|
|
}
|