15fe11e25SDavid du Colombier /* code from mark huckvale: http://www.phon.ucl.ac.uk/home/mark/sudoku/ */
25fe11e25SDavid du Colombier
35fe11e25SDavid du Colombier #include <u.h>
45fe11e25SDavid du Colombier #include <libc.h>
55fe11e25SDavid du Colombier #include <draw.h>
65fe11e25SDavid du Colombier #include <event.h>
75fe11e25SDavid du Colombier
85fe11e25SDavid du Colombier #include "sudoku.h"
95fe11e25SDavid du Colombier
105fe11e25SDavid du Colombier char *imgdir = "/sys/games/lib/sudoku/images";
115fe11e25SDavid du Colombier char *lvldir = "/sys/games/lib/sudoku/boards"; /* level library dir */
125fe11e25SDavid du Colombier
135fe11e25SDavid du Colombier int selected; /* which digit do we have selected? */
145fe11e25SDavid du Colombier
155fe11e25SDavid du Colombier Image *background; /* DPaleyellow */
165fe11e25SDavid du Colombier Image *backselect; /* DPalebluegreen */
175fe11e25SDavid du Colombier Image *blink; /* DDarkyellow */
185fe11e25SDavid du Colombier Image *brdr; /* 0x55555555 */
195fe11e25SDavid du Colombier Image *fixed; /* DBlue */
205fe11e25SDavid du Colombier Image *wrong; /* DRed */
215fe11e25SDavid du Colombier Image *dig[10]; /* digit masks */
225fe11e25SDavid du Colombier
235fe11e25SDavid du Colombier Dir *dir;
245fe11e25SDavid du Colombier int numlevels;
255fe11e25SDavid du Colombier int curlevel;
265fe11e25SDavid du Colombier
275fe11e25SDavid du Colombier char *buttons[] =
285fe11e25SDavid du Colombier {
295fe11e25SDavid du Colombier "new",
305fe11e25SDavid du Colombier "check",
315fe11e25SDavid du Colombier "solve",
325fe11e25SDavid du Colombier "clear",
335fe11e25SDavid du Colombier "save",
345fe11e25SDavid du Colombier "load",
355fe11e25SDavid du Colombier "print",
365fe11e25SDavid du Colombier "offline",
375fe11e25SDavid du Colombier "exit",
385fe11e25SDavid du Colombier 0
395fe11e25SDavid du Colombier };
405fe11e25SDavid du Colombier
415fe11e25SDavid du Colombier Menu menu =
425fe11e25SDavid du Colombier {
435fe11e25SDavid du Colombier buttons
445fe11e25SDavid du Colombier };
455fe11e25SDavid du Colombier
465fe11e25SDavid du Colombier Menu lmenu =
475fe11e25SDavid du Colombier {
485fe11e25SDavid du Colombier nil,
495fe11e25SDavid du Colombier genlevels,
505fe11e25SDavid du Colombier 0,
515fe11e25SDavid du Colombier };
525fe11e25SDavid du Colombier
535fe11e25SDavid du Colombier int
readlevels(char * leveldir)545fe11e25SDavid du Colombier readlevels(char *leveldir)
555fe11e25SDavid du Colombier {
565fe11e25SDavid du Colombier int fd, n;
575fe11e25SDavid du Colombier
585fe11e25SDavid du Colombier if((fd = open(leveldir, OREAD)) < 0)
595fe11e25SDavid du Colombier return -1;
605fe11e25SDavid du Colombier
615fe11e25SDavid du Colombier n = dirreadall(fd, &dir);
625fe11e25SDavid du Colombier close(fd);
635fe11e25SDavid du Colombier
645fe11e25SDavid du Colombier return n;
655fe11e25SDavid du Colombier }
665fe11e25SDavid du Colombier
675fe11e25SDavid du Colombier char *
genlevels(int i)685fe11e25SDavid du Colombier genlevels(int i)
695fe11e25SDavid du Colombier {
705fe11e25SDavid du Colombier if(numlevels == 0)
715fe11e25SDavid du Colombier numlevels = readlevels(lvldir);
725fe11e25SDavid du Colombier
735fe11e25SDavid du Colombier if(numlevels > 0 && i < numlevels)
745fe11e25SDavid du Colombier return (dir+i)->name;
755fe11e25SDavid du Colombier
765fe11e25SDavid du Colombier return nil;
775fe11e25SDavid du Colombier }
785fe11e25SDavid du Colombier
795fe11e25SDavid du Colombier void
convert(Cell * brd,int * board)805fe11e25SDavid du Colombier convert(Cell *brd, int *board)
815fe11e25SDavid du Colombier {
825fe11e25SDavid du Colombier int i;
835fe11e25SDavid du Colombier
845fe11e25SDavid du Colombier for(i = 0; i < Psize; i++) {
855fe11e25SDavid du Colombier brd[i].digit = board[i] & Digit;
865fe11e25SDavid du Colombier if(brd[i].digit < 0 || brd[i].digit > 9)
875fe11e25SDavid du Colombier brd[i].digit = -1;
885fe11e25SDavid du Colombier brd[i].solve = (board[i] & Solve) >> 4;
895fe11e25SDavid du Colombier brd[i].locked = board[i] & MLock;
905fe11e25SDavid du Colombier }
915fe11e25SDavid du Colombier memcpy(obrd, brd, Psize * sizeof(Cell));
925fe11e25SDavid du Colombier }
935fe11e25SDavid du Colombier
945fe11e25SDavid du Colombier Image *
eallocimage(Rectangle r,int repl,uint color)955fe11e25SDavid du Colombier eallocimage(Rectangle r, int repl, uint color)
965fe11e25SDavid du Colombier {
975fe11e25SDavid du Colombier Image *tmp;
985fe11e25SDavid du Colombier
995fe11e25SDavid du Colombier tmp = allocimage(display, r, screen->chan, repl, color);
1005fe11e25SDavid du Colombier if(tmp == nil)
1015fe11e25SDavid du Colombier sysfatal("cannot allocate buffer image: %r");
1025fe11e25SDavid du Colombier
1035fe11e25SDavid du Colombier return tmp;
1045fe11e25SDavid du Colombier }
1055fe11e25SDavid du Colombier
1065fe11e25SDavid du Colombier Image *
eloadfile(char * path)1075fe11e25SDavid du Colombier eloadfile(char *path)
1085fe11e25SDavid du Colombier {
1095fe11e25SDavid du Colombier Image *img;
1105fe11e25SDavid du Colombier int fd;
1115fe11e25SDavid du Colombier
1125fe11e25SDavid du Colombier fd = open(path, OREAD);
1135fe11e25SDavid du Colombier if(fd < 0) {
1145fe11e25SDavid du Colombier fprint(2, "cannot open image file %s: %r\n", path);
1155fe11e25SDavid du Colombier exits("image");
1165fe11e25SDavid du Colombier }
1175fe11e25SDavid du Colombier img = readimage(display, fd, 0);
1185fe11e25SDavid du Colombier if(img == nil)
1195fe11e25SDavid du Colombier sysfatal("cannot load image: %r");
1205fe11e25SDavid du Colombier close(fd);
1215fe11e25SDavid du Colombier
1225fe11e25SDavid du Colombier return img;
1235fe11e25SDavid du Colombier }
1245fe11e25SDavid du Colombier
1255fe11e25SDavid du Colombier
1265fe11e25SDavid du Colombier void
clearboard(Cell * board)1275fe11e25SDavid du Colombier clearboard(Cell *board)
1285fe11e25SDavid du Colombier {
1295fe11e25SDavid du Colombier int i;
1305fe11e25SDavid du Colombier
1315fe11e25SDavid du Colombier for(i = 0; i < Psize; i++) {
1325fe11e25SDavid du Colombier board[i].digit = -1;
1335fe11e25SDavid du Colombier board[i].solve = 0;
1345fe11e25SDavid du Colombier board[i].locked = 0;
1355fe11e25SDavid du Colombier }
1365fe11e25SDavid du Colombier }
1375fe11e25SDavid du Colombier
1385fe11e25SDavid du Colombier void
solveboard(Cell * board)1395fe11e25SDavid du Colombier solveboard(Cell *board)
1405fe11e25SDavid du Colombier {
1415fe11e25SDavid du Colombier int i;
1425fe11e25SDavid du Colombier
1435fe11e25SDavid du Colombier for(i = 0; i < Psize; i++) {
1445fe11e25SDavid du Colombier board[i].digit = board[i].solve;
1455fe11e25SDavid du Colombier }
1465fe11e25SDavid du Colombier }
1475fe11e25SDavid du Colombier
1485fe11e25SDavid du Colombier
1495fe11e25SDavid du Colombier int
checkpossible(Cell * board,int x,int y,int num)1505fe11e25SDavid du Colombier checkpossible(Cell *board, int x, int y, int num)
1515fe11e25SDavid du Colombier {
1525fe11e25SDavid du Colombier int i, j;
1535fe11e25SDavid du Colombier
1545fe11e25SDavid du Colombier for(i = 0; i < Brdsize; i++) {
1555fe11e25SDavid du Colombier if(board[i*Brdsize + y].digit == num && i != x)
1565fe11e25SDavid du Colombier return 0;
1575fe11e25SDavid du Colombier if(board[x*Brdsize + i].digit == num && i != y)
1585fe11e25SDavid du Colombier return 0;
1595fe11e25SDavid du Colombier }
1605fe11e25SDavid du Colombier
1615fe11e25SDavid du Colombier for(i = x - (x%3); i < x - (x%3) + 3; i++)
1625fe11e25SDavid du Colombier for(j = y - (y%3); j < y - (y%3) + 3; j++)
1635fe11e25SDavid du Colombier if((i != x && j != y) && board[i*Brdsize + j].digit == num)
1645fe11e25SDavid du Colombier return 0;
1655fe11e25SDavid du Colombier
1665fe11e25SDavid du Colombier return 1;
1675fe11e25SDavid du Colombier }
1685fe11e25SDavid du Colombier
1695fe11e25SDavid du Colombier void
resize(void)1705fe11e25SDavid du Colombier resize(void)
1715fe11e25SDavid du Colombier {
1725fe11e25SDavid du Colombier int fd;
1735fe11e25SDavid du Colombier
1745fe11e25SDavid du Colombier fd = open("/dev/wctl", OWRITE);
1755fe11e25SDavid du Colombier if(fd >= 0){
1765fe11e25SDavid du Colombier fprint(fd, "resize -dx %d -dy %d", Maxx, Maxy);
1775fe11e25SDavid du Colombier close(fd);
1785fe11e25SDavid du Colombier }
1795fe11e25SDavid du Colombier
1805fe11e25SDavid du Colombier }
1815fe11e25SDavid du Colombier
1825fe11e25SDavid du Colombier void
drawcell(int x,int y,int num,Image * col)1835fe11e25SDavid du Colombier drawcell(int x, int y, int num, Image *col)
1845fe11e25SDavid du Colombier {
1855fe11e25SDavid du Colombier Rectangle r = Rect(x*Square, y*Square, (x+1)*Square, (y+1)*Square);
1865fe11e25SDavid du Colombier
1875fe11e25SDavid du Colombier if(num < 0 || num > 9)
1885fe11e25SDavid du Colombier return;
1895fe11e25SDavid du Colombier
1905fe11e25SDavid du Colombier r = insetrect(r, Border);
1915fe11e25SDavid du Colombier r = rectaddpt(r, Pt(0, Square));
1925fe11e25SDavid du Colombier r.max = addpt(r.max, Pt(2, 2));
1935fe11e25SDavid du Colombier
1945fe11e25SDavid du Colombier draw(screen, rectaddpt(r, screen->r.min), col, dig[num], ZP);
1955fe11e25SDavid du Colombier }
1965fe11e25SDavid du Colombier
1975fe11e25SDavid du Colombier void
drawboard(void)1985fe11e25SDavid du Colombier drawboard(void)
1995fe11e25SDavid du Colombier {
2005fe11e25SDavid du Colombier int i;
2015fe11e25SDavid du Colombier
2025fe11e25SDavid du Colombier for(i = 0; i < Psize; i++) {
2035fe11e25SDavid du Colombier drawcell(i / Brdsize, i % Brdsize, brd[i].digit, brd[i].locked ? fixed : display->black);
2045fe11e25SDavid du Colombier }
2055fe11e25SDavid du Colombier }
2065fe11e25SDavid du Colombier
2075fe11e25SDavid du Colombier void
drawchecked(Cell * brd)2085fe11e25SDavid du Colombier drawchecked(Cell *brd)
2095fe11e25SDavid du Colombier {
2105fe11e25SDavid du Colombier int i;
2115fe11e25SDavid du Colombier
2125fe11e25SDavid du Colombier for(i = 0; i < Psize; i++) {
2135fe11e25SDavid du Colombier if(brd[i].locked)
2145fe11e25SDavid du Colombier drawcell(i / Brdsize, i % Brdsize, brd[i].digit, fixed);
2155fe11e25SDavid du Colombier else
2165fe11e25SDavid du Colombier drawcell(i / Brdsize, i % Brdsize, brd[i].digit,
2175fe11e25SDavid du Colombier checkpossible(brd, i / Brdsize, i % Brdsize, brd[i].digit) ? display->black : wrong);
2185fe11e25SDavid du Colombier }
2195fe11e25SDavid du Colombier }
2205fe11e25SDavid du Colombier
2215fe11e25SDavid du Colombier void
drawscreen(void)2225fe11e25SDavid du Colombier drawscreen(void)
2235fe11e25SDavid du Colombier {
2245fe11e25SDavid du Colombier Point l1, l2;
2255fe11e25SDavid du Colombier int i;
2265fe11e25SDavid du Colombier
2275fe11e25SDavid du Colombier draw(screen, screen->r, brdr, nil, ZP);
2285fe11e25SDavid du Colombier draw(screen, insetrect(screen->r, Border), background, nil, ZP);
2295fe11e25SDavid du Colombier for(i = 0; i < Brdsize; i++) {
2305fe11e25SDavid du Colombier l1 = addpt(screen->r.min, Pt(i*Square, Square));
2315fe11e25SDavid du Colombier l2 = addpt(screen->r.min, Pt(i*Square, Maxy));
2325fe11e25SDavid du Colombier line(screen, l1, l2, Endsquare, Endsquare, (i%3) == 0 ? Thickline : Line, brdr, ZP);
2335fe11e25SDavid du Colombier l1 = addpt(screen->r.min, Pt(0, (i+1)*Square));
2345fe11e25SDavid du Colombier l2 = addpt(screen->r.min, Pt(Maxx, (i+1)*Square));
2355fe11e25SDavid du Colombier line(screen, l1, l2, Endsquare, Endsquare, (i%3) == 0 ? Thickline : Line, brdr, ZP);
2365fe11e25SDavid du Colombier }
2375fe11e25SDavid du Colombier for(i = 1; i < 10; i++) {
2385fe11e25SDavid du Colombier drawbar(i, (selected == i) ? 1 : 0);
2395fe11e25SDavid du Colombier }
2405fe11e25SDavid du Colombier drawboard();
2415fe11e25SDavid du Colombier flushimage(display, 1);
2425fe11e25SDavid du Colombier }
2435fe11e25SDavid du Colombier
2445fe11e25SDavid du Colombier
2455fe11e25SDavid du Colombier void
drawbar(int digit,int selected)2465fe11e25SDavid du Colombier drawbar(int digit, int selected)
2475fe11e25SDavid du Colombier {
2485fe11e25SDavid du Colombier Rectangle r = Rect((digit - 1)*Square, 0, digit*Square, Square);
2495fe11e25SDavid du Colombier
2505fe11e25SDavid du Colombier if(digit < 1 || digit > 9)
2515fe11e25SDavid du Colombier return;
2525fe11e25SDavid du Colombier
2535fe11e25SDavid du Colombier r = insetrect(r, Border);
2545fe11e25SDavid du Colombier r.max = addpt(r.max, Pt(2, 2));
2555fe11e25SDavid du Colombier draw(screen, rectaddpt(r, screen->r.min), selected ? backselect : background, nil, ZP);
2565fe11e25SDavid du Colombier draw(screen, rectaddpt(r, screen->r.min), display->black, dig[digit-1], ZP);
2575fe11e25SDavid du Colombier }
2585fe11e25SDavid du Colombier
2595fe11e25SDavid du Colombier void
eresized(int new)2605fe11e25SDavid du Colombier eresized(int new)
2615fe11e25SDavid du Colombier {
2625fe11e25SDavid du Colombier Point p;
2635fe11e25SDavid du Colombier char path[256];
2645fe11e25SDavid du Colombier int i;
2655fe11e25SDavid du Colombier
2665fe11e25SDavid du Colombier if(new && getwindow(display, Refnone) < 0)
2675fe11e25SDavid du Colombier sysfatal("can't reattach to window");
2685fe11e25SDavid du Colombier
2695fe11e25SDavid du Colombier if(background == nil)
2705fe11e25SDavid du Colombier background = eallocimage(Rect(0, 0, 1, 1), 1, DPaleyellow);
2715fe11e25SDavid du Colombier if(backselect == nil)
2725fe11e25SDavid du Colombier backselect = eallocimage(Rect(0, 0, 1, 1), 1, DPalebluegreen);
2735fe11e25SDavid du Colombier if(blink == nil)
2745fe11e25SDavid du Colombier blink = eallocimage(Rect(0, 0, 1, 1), 1, DDarkyellow);
2755fe11e25SDavid du Colombier if(brdr == nil)
2765fe11e25SDavid du Colombier brdr = eallocimage(Rect(0, 0, 1, 1), 1, 0x55555555);
2775fe11e25SDavid du Colombier if(fixed == nil)
2785fe11e25SDavid du Colombier fixed = eallocimage(Rect(0, 0, 1, 1), 1, DBlue);
2795fe11e25SDavid du Colombier if(wrong == nil)
2805fe11e25SDavid du Colombier wrong = eallocimage(Rect(0, 0, 1, 1), 1, DRed);
2815fe11e25SDavid du Colombier if(dig[0] == nil) {
2825fe11e25SDavid du Colombier for(i = 0; i < 9; i++) {
2835fe11e25SDavid du Colombier snprint(path, 256, "%s/%d.bit", imgdir, i+1);
2845fe11e25SDavid du Colombier dig[i] = eloadfile(path);
2855fe11e25SDavid du Colombier }
2865fe11e25SDavid du Colombier }
2875fe11e25SDavid du Colombier
2885fe11e25SDavid du Colombier p = Pt(Dx(screen->r), Dy(screen->r));
289*d8f3f65eSDavid du Colombier if(!new || !eqpt(p, Pt(Maxx - 8, Maxy - 8)))
2905fe11e25SDavid du Colombier resize();
291*d8f3f65eSDavid du Colombier
2925fe11e25SDavid du Colombier drawscreen();
2935fe11e25SDavid du Colombier }
2945fe11e25SDavid du Colombier
2955fe11e25SDavid du Colombier void
main(int argc,char * argv[])2965fe11e25SDavid du Colombier main(int argc, char *argv[])
2975fe11e25SDavid du Colombier {
2985fe11e25SDavid du Colombier Mouse m;
2995fe11e25SDavid du Colombier Event e;
3005fe11e25SDavid du Colombier Point p;
3015fe11e25SDavid du Colombier int last1 = 0; /* was the button clicked last time? */
3025fe11e25SDavid du Colombier
3035fe11e25SDavid du Colombier USED(argc, argv);
3045fe11e25SDavid du Colombier
3055fe11e25SDavid du Colombier if(initdraw(nil, nil, "sudoku") < 0)
3065fe11e25SDavid du Colombier sysfatal("initdraw failed: %r");
3075fe11e25SDavid du Colombier
3085fe11e25SDavid du Colombier einit(Emouse|Ekeyboard);
3095fe11e25SDavid du Colombier
3105fe11e25SDavid du Colombier
3115fe11e25SDavid du Colombier clearboard(brd);
3125fe11e25SDavid du Colombier eresized(0);
3135fe11e25SDavid du Colombier
3145fe11e25SDavid du Colombier srand(time(0)*getpid());
3155fe11e25SDavid du Colombier makep();
3165fe11e25SDavid du Colombier convert(brd, board);
3175fe11e25SDavid du Colombier
3185fe11e25SDavid du Colombier drawscreen();
3195fe11e25SDavid du Colombier for(;;) {
3205fe11e25SDavid du Colombier switch(event(&e)) {
3215fe11e25SDavid du Colombier case Emouse:
3225fe11e25SDavid du Colombier m = e.mouse;
3235fe11e25SDavid du Colombier if(m.buttons&1) {
3245fe11e25SDavid du Colombier if(last1 == 0) {
3255fe11e25SDavid du Colombier last1 = 1;
3265fe11e25SDavid du Colombier p = subpt(m.xy, screen->r.min);
3275fe11e25SDavid du Colombier if(ptinrect(p, Rect(0, 0, Maxx, Square+Border))) {
3285fe11e25SDavid du Colombier if(p.x/Square == selected - 1) {
3295fe11e25SDavid du Colombier drawbar(selected, 0);
3305fe11e25SDavid du Colombier selected = 0;
3315fe11e25SDavid du Colombier } else {
3325fe11e25SDavid du Colombier selected = p.x/Square + 1;
3335fe11e25SDavid du Colombier }
3345fe11e25SDavid du Colombier } else {
3355fe11e25SDavid du Colombier Point lp = divpt(p, Square);
3365fe11e25SDavid du Colombier lp.y--;
3375fe11e25SDavid du Colombier
3385fe11e25SDavid du Colombier if(brd[lp.x * Brdsize + lp.y].locked)
3395fe11e25SDavid du Colombier break;
3405fe11e25SDavid du Colombier
3415fe11e25SDavid du Colombier if(selected) {
3425fe11e25SDavid du Colombier brd[lp.x * Brdsize + lp.y].digit = selected - 1;
3435fe11e25SDavid du Colombier } else {
3445fe11e25SDavid du Colombier brd[lp.x * Brdsize + lp.y].digit = -1;
3455fe11e25SDavid du Colombier }
3465fe11e25SDavid du Colombier }
3475fe11e25SDavid du Colombier drawscreen();
3485fe11e25SDavid du Colombier }
3495fe11e25SDavid du Colombier } else {
3505fe11e25SDavid du Colombier last1 = 0;
3515fe11e25SDavid du Colombier }
3525fe11e25SDavid du Colombier
3535fe11e25SDavid du Colombier if(m.buttons&2) {
3545fe11e25SDavid du Colombier char *str;
3555fe11e25SDavid du Colombier int l;
3565fe11e25SDavid du Colombier /* levels start from 1 */
3575fe11e25SDavid du Colombier lmenu.lasthit = curlevel;
3585fe11e25SDavid du Colombier l = emenuhit(2, &m, &lmenu);
3595fe11e25SDavid du Colombier if(l >= 0){
3605fe11e25SDavid du Colombier curlevel = l;
3615fe11e25SDavid du Colombier str = smprint("%s/%s", lvldir, (dir+curlevel)->name);
3625fe11e25SDavid du Colombier if(loadlevel(str, brd) < 0)
3635fe11e25SDavid du Colombier clearboard(brd);
3645fe11e25SDavid du Colombier memcpy(obrd, brd, Psize * sizeof(Cell));
3655fe11e25SDavid du Colombier free(str);
3665fe11e25SDavid du Colombier }
3675fe11e25SDavid du Colombier drawscreen();
3685fe11e25SDavid du Colombier }
3695fe11e25SDavid du Colombier if(m.buttons&4) {
3705fe11e25SDavid du Colombier switch(emenuhit(3, &m, &menu)) {
3715fe11e25SDavid du Colombier case 0: /* new */
3725fe11e25SDavid du Colombier makep();
3735fe11e25SDavid du Colombier convert(brd, board);
3745fe11e25SDavid du Colombier drawscreen();
3755fe11e25SDavid du Colombier break;
3765fe11e25SDavid du Colombier case 1: /* solve */
3775fe11e25SDavid du Colombier drawchecked(brd);
3785fe11e25SDavid du Colombier break;
3795fe11e25SDavid du Colombier case 2: /* solve */
3805fe11e25SDavid du Colombier solveboard(brd);
3815fe11e25SDavid du Colombier drawscreen();
3825fe11e25SDavid du Colombier break;
3835fe11e25SDavid du Colombier case 3: /* clear */
3845fe11e25SDavid du Colombier memcpy(brd, obrd, Psize * sizeof(Cell));
3855fe11e25SDavid du Colombier drawscreen();
3865fe11e25SDavid du Colombier break;
3875fe11e25SDavid du Colombier case 4: /* save */
3885fe11e25SDavid du Colombier savegame(brd);
3895fe11e25SDavid du Colombier drawscreen();
3905fe11e25SDavid du Colombier break;
3915fe11e25SDavid du Colombier case 5: /* load */
3925fe11e25SDavid du Colombier if(loadgame(brd) < 0) {
3935fe11e25SDavid du Colombier clearboard(brd);
3945fe11e25SDavid du Colombier }
3955fe11e25SDavid du Colombier memcpy(obrd, brd, Psize * sizeof(Cell));
3965fe11e25SDavid du Colombier drawscreen();
3975fe11e25SDavid du Colombier break;
3985fe11e25SDavid du Colombier case 6: /* print */
3995fe11e25SDavid du Colombier printboard(brd);
4005fe11e25SDavid du Colombier break;
4015fe11e25SDavid du Colombier case 7: /* offline */
4025fe11e25SDavid du Colombier fprettyprintbrd(brd);
4035fe11e25SDavid du Colombier break;
4045fe11e25SDavid du Colombier case 8: /* exit */
4055fe11e25SDavid du Colombier exits(nil);
4065fe11e25SDavid du Colombier }
4075fe11e25SDavid du Colombier }
4085fe11e25SDavid du Colombier break;
4095fe11e25SDavid du Colombier
4105fe11e25SDavid du Colombier case Ekeyboard:
4115fe11e25SDavid du Colombier switch(e.kbdc) {
4125fe11e25SDavid du Colombier case 127:
4135fe11e25SDavid du Colombier case 'q':
4145fe11e25SDavid du Colombier case 'Q':
4155fe11e25SDavid du Colombier exits(nil);
4165fe11e25SDavid du Colombier default:
4175fe11e25SDavid du Colombier break;
4185fe11e25SDavid du Colombier }
4195fe11e25SDavid du Colombier break;
4205fe11e25SDavid du Colombier }
4215fe11e25SDavid du Colombier }
4225fe11e25SDavid du Colombier }
423