From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: To: 9fans@cse.psu.edu Subject: Re: [9fans] 150-solitiare From: "Russ Cox" In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Date: Mon, 31 Mar 2003 00:36:01 -0500 Topicbox-Message-UUID: 876795fc-eacb-11e9-9e20-41e7f4b1d025 I started a gui in Limbo some years ago. This might be a good starting point. I don't remember how far I got. The /usr/rsc/cards directory is lost, but I had filled it with cards downloaded off the net and converted to Inferno format. implement Solitaire; include "sys.m"; sys: Sys; print, sprint: import sys; include "draw.m"; draw: Draw; include "tk.m"; tk: Tk; include "wmlib.m"; wmlib: Wmlib; include "rand.m"; rand: Rand; include "daytime.m"; daytime: Daytime; Solitaire: module { init: fn(ctxt: ref Draw->Context, argv: list of string); }; t: ref Tk->Toplevel; # bad name for a global msglab: string; # label for messages ace: array of ref Cardstack; pile: array of ref Cardstack; deck: ref Cardstack; dealt: ref Cardstack; suits: con "chds"; # clubs, hearts, diamonds, spades; carddir: con "@/usr/rsc/cards"; TABLEHT: con 450; TABLEWID: con 580; XPAD: con 5; YPAD: con 20; YUPLAP: con 17; YDNLAP: con 4; XLAP: con 17; CARDHT: con 96; CARDWID: con 71; init(ctxt: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; draw = load Draw Draw->PATH; tk = load Tk Tk->PATH; wmlib = load Wmlib Wmlib->PATH; rand = load Rand Rand->PATH; daytime = load Daytime Daytime->PATH; wmlib->init(); (t1, menubut) := wmlib->titlebar(ctxt.screen, "", "Solitaire", Wmlib->Hide); t = t1; tk->cmd(t, "image create bitmap waiting -file cursor.wait"); tk->cmd(t, "pack .Wm_t .c -side top -fill x"); readcards(); cmd := chan of string; tk->namechan(t, cmd, "cmd"); tk->cmd(t, sprint("canvas .c -height %d -width %d -background green", TABLEHT, TABLEWID)); tk->cmd(t, "pack .Wm_t .c -side top -fill x"); tk->cmd(t, "bind .c {send cmd B1down %x %y}"); tk->cmd(t, "bind .c {send cmd B1move %x %y}"); tk->cmd(t, "update"); deal(); drawboard(); for (;;) { x0, y0, x, y: int; alt { s := <- cmd => (n, l) := sys->tokenize(s, " \t"); case hd l { "Quit" => exit; "Reset" => deal(); "Enter" => print("enter %s\n", hd tl l); "Leave" => print("leave %s\n", hd tl l); "B1down" => x0 = int hd tl l; y0 = int hd tl tl l; # mouseDown(x0, y0); "B1move" => x = int hd tl l; y = int hd tl tl l; # mouseMove(x, y); "B1up" => x = int hd tl l; y = int hd tl tl l; # mouseUp(x0, y0, x, y); } menu := <-menubut => if(menu[0] == 'e'){ exit; } wmlib->titlectl(t, menu); } } } deal() { ace = array[4] of ref Cardstack; pile = array[7] of ref Cardstack; for(i:=0; i<4; i++) { c : Cardstack; ace[i] = ref c; ace[i].init(13, "ace_"+string i); } for(i=0; i<7; i++) { c : Cardstack; pile[i] = ref c; pile[i].init(13+7, "pile_"+string i); } c : Cardstack; dealt = ref c; dealt.init(52, "dealt"); deck = shuffle(); for(i=0; i<7; i++) { for(j:=i; j<7; j++) { c := deck.pop(); if(i == j) c.faceup++; pile[j].push(c); } } for(i=0; i<5; i++) { c := deck.pop(); c.faceup++; dealt.push(c); } boardmath(); } drawboard() { # for(i:=0; i<7; i++) # pile[i].draw(); # for(i=0; i<4; i++) # ace[i].draw(); # deck.draw(); dealt.drawm(3); } boardmath() { i, x, y, xlap, yuplap, ydnlap: int; x = XPAD; y = YPAD+CARDHT+YPAD; for(i=0; i<7; i++) { pile[i].x = x; pile[i].y = y; pile[i].xlap = 0; pile[i].yuplap = YUPLAP; pile[i].ydnlap = YDNLAP; x += CARDWID+XPAD; } x = pile[7-4].x; y = YPAD; for(i=0; i<4; i++) { ace[i].x = x; ace[i].y = y; ace[i].xlap = 0; ace[i].yuplap = ace[i].ydnlap = 0; x += CARDWID+XPAD; } deck.x = XPAD; deck.y = YPAD; deck.xlap = deck.yuplap = deck.ydnlap = 0; dealt.x = XPAD+CARDWID+XPAD; dealt.y = YPAD; dealt.xlap = XLAP; dealt.yuplap = dealt.ydnlap = 0; } shuffle() : ref Cardstack { order := array[52] of int; for(i:=0; i<52; i++) order[i] = i; rand->init(daytime->now()); for(i=52; i>0; i--) { r := rand->rand(i); (order[i-1], order[r]) = (order[r], order[i-1]); } cs : Cardstack; rcs := ref cs; rcs.init(52, "deck"); for(i=0; i<52; i++) { c : Card; j := order[i]; c.index = j; c.name = suits[j/13:j/13+1] + string(j%13+1); c.faceup = 0; rcs.push(c); } return rcs; } readcards() { tk->cmd(t, "cursor -image waiting; update"); s : string; for(i := 1; i <= 13; i++) { for(c := 0; c < len suits; c++) { f := suits[c:c+1] + string i; getcard("cbit_"+f, f); } } getcard("cbit_back", "back"); tk->cmd(t, sprint("image create bitmap cbit_none "+ "-file %s/none.bit -maskfile %s/none.mask", carddir, carddir)); tk->cmd(t, "cursor -default; update"); } getcard(card, bitmap: string) { tk->cmd(t, sprint("image create bitmap %s -file %s/%s.bit -maskfile %s/card.mask", card, carddir, bitmap, carddir)); } xcmd(t: ref Tk->Toplevel, s: string) { i := tk->cmd(t, s); sys->print("%s returns %s...\n", s, i); } Card: adt { index: int; name: string; faceup: int; draw: fn(c: self Card, x, y: int); }; cardat(x,y: int, name, img: string) { tk->cmd(t, sprint(".c delete %s", name)); xcmd(t, sprint(".c create image %d %d -image %s -tags %s", x+CARDWID/2, y+CARDHT/2, img, name)); xcmd(t, sprint("bind .c.%s {send cmd Enter %s}", name, name)); tk->cmd(t, sprint("bind .c.%s {send cmd Leave %s}", name, name)); } Card.draw(c: self Card, x, y: int) { if(c.faceup) cardat(x, y, "card_"+c.name, "cbit_"+c.name); else cardat(x, y, "card_"+c.name, "cbit_back"); } Cardstack: adt { c: array of Card; n, sz: int; xlap, yuplap, ydnlap: int; x, y: int; name: string; pop: fn(cs: self ref Cardstack) : Card; push: fn(cs: self ref Cardstack, c: Card); init: fn(cs: self ref Cardstack, sz: int, s: string); putarray: fn(cs: self ref Cardstack, ca: array of Card); draw: fn(cs: self ref Cardstack); drawm: fn(cs: self ref Cardstack, m: int); }; Cardstack.pop(cs: self ref Cardstack) : Card { if(cs.n > 0) return cs.c[--cs.n]; rv : Card; rv.index = -1; return rv; } Cardstack.push(cs: self ref Cardstack, c: Card) { if(cs.n < cs.sz) cs.c[cs.n++] = c; } Cardstack.init(cs: self ref Cardstack, sz: int, s:string) { cs.sz = sz; cs.c = array[sz] of Card; cs.n = 0; cs.name = s; } Cardstack.putarray(cs: self ref Cardstack, ca: array of Card) { for(i:=0; icmd(t, "update"); } Cardstack.drawm(cs: self ref Cardstack, max: int) { x := cs.x; y := cs.y; cardat(x, y, cs.name, "cbit_none"); i := cs.n-max; if(i < 0) i = 0; for(;icmd(t, "update"); }