home *** CD-ROM | disk | FTP | other *** search
- program QUEEN;
-
- uses wintypes, winprocs, wobjects;
- const
- appname : pchar = 'Queen';
- var
- back : integer;
- face : array[1..10] of hbitmap;
- type
- tmyapplication = object(tapplication)
- procedure initmainwindow; virtual;
- end;
- pdeckwindow = ^tdeckwindow;
- tdeckwindow = object(twindow)
- oldback, newback : integer;
- constructor init(aparent : pwindowsobject; aname : pchar);
- procedure frameit(dc : hdc);
- procedure paint(dc : hdc; var ps : tpaintstruct); virtual;
- procedure pressok(var msg : tmessage); virtual id_first + id_ok;
- procedure wmlbuttondown(var msg : tmessage); virtual wm_first + wm_lbuttondown;
- end;
- pqueenwindow = ^tqueenwindow;
- tqueenwindow = object(twindow)
- cardsize, newrect : trect;
- newgx, newgy, level : integer;
- move : array[1..3] of integer;
- buttondown, moved, fin : boolean;
- card : array[1..53] of hbitmap;
- dealt : array[1..52] of boolean;
- game : array[1..55] of record
- deck : 1..53;
- gx, gy : integer;
- row : 1..11;
- col : 1..24;
- canopen, canmove, opened, onscreen : boolean;
- end;
- pos : array[1..11, 1..24] of record
- num : 1..53;
- px, py : integer;
- rects : trect;
- end;
- constructor init(aparent : pwindowsobject; aname : pchar);
- procedure defcommandproc(var msg : tmessage); virtual;
- procedure drawbmp(dc : hdc; x, y : integer; size : trect; bitmap : hbitmap);
- function getclassname : pchar; virtual;
- procedure getwindowclass(var awndclass : twndclass); virtual;
- procedure moving;
- procedure newgame;
- procedure paint(dc : hdc; var ps : tpaintstruct); virtual;
- procedure setupwindow; virtual;
- procedure wmdestroy(var msg : tmessage); virtual wm_first + wm_destroy;
- procedure wmlbuttondown(var msg : tmessage); virtual wm_first + wm_lbuttondown;
- procedure wmlbuttonup(var msg : tmessage); virtual wm_first + wm_lbuttonup;
- procedure wmmousemove(var msg : tmessage); virtual wm_first + wm_mousemove;
- procedure wmrbuttondown(var msg : tmessage); virtual wm_first + wm_rbuttondown;
- procedure wmtimer(var msg : tmessage); virtual wm_first + wm_timer;
- end;
-
- constructor tdeckwindow.init(aparent : pwindowsobject; aname : pchar);
- var pbuttonok : pbutton;
- begin
- twindow.init(aparent, aname);
- with attr do begin
- style := ws_caption or ws_visible;
- x := 100; y := 100;
- w := 280; h := 200;
- end;
- pbuttonok := new(pbutton, init(@self, id_ok, '&Ok', 110, 140, 60, 30, false));
- oldback := back;
- newback := back;
- end;
-
- procedure tdeckwindow.frameit(dc : hdc);
- var i1, x, y : integer;
- pbrush : hbrush;
- rect : trect;
- begin
- x := 20 + 50 * ((oldback - 1) mod 5);
- y := 10 + 64 * ((oldback - 1) div 5);
- setrect(rect, x, y, x + 40, y + 54);
- inflaterect(rect, 2, 2);
- pbrush := getstockobject(white_brush);
- for i1 := 1 to 3 do begin
- inflaterect(rect, 1, 1);
- framerect(dc, rect, pbrush);
- end;
- x := 20 + 50 * ((newback - 1) mod 5);
- y := 10 + 64 * ((newback - 1) div 5);
- setrect(rect, x, y, x + 40, y + 54);
- inflaterect(rect, 2, 2);
- pbrush := getstockobject(gray_brush);
- for i1 := 1 to 3 do begin
- inflaterect(rect, 1, 1);
- framerect(dc, rect, pbrush);
- end;
- oldback := newback;
- end;
-
- procedure tdeckwindow.paint(dc : hdc; var ps : tpaintstruct);
- var i1, i2, x, y : integer;
- memdc : hdc;
- begin
- memdc := createcompatibledc(dc);
- for i1 := 1 to 2 do
- for i2 := 1 to 5 do begin
- selectobject(memdc, face[i2 + 5 * (i1 - 1)]);
- x := 20 + 50 * (i2 - 1);
- y := 10 + 64 * (i1 - 1);
- stretchblt(dc, x, y, 40, 54, memdc, 0, 0, 71, 96, srccopy);
- end;
- frameit(dc);
- deletedc(memdc);
- end;
-
- procedure tdeckwindow.pressok(var msg : tmessage);
- begin
- closewindow;
- if back <> oldback then begin
- back := oldback;
- with pqueenwindow(parent)^ do
- if not game[52].opened then card[53] := face[back];
- invalidaterect(hwindow, nil, true);
- end;
- end;
-
- procedure tdeckwindow.wmlbuttondown(var msg : tmessage);
- var i1, i2, x, y : integer;
- rect : trect;
- dc : hdc;
- begin
- for i1 := 1 to 2 do
- for i2 := 1 to 5 do begin
- x := 20 + 50 * (i2 - 1);
- y := 10 + 64 * (i1 - 1);
- setrect(rect, x, y, x + 40, y + 54);
- if ptinrect(rect, tpoint(msg.lparam)) then begin
- newback := i2 + 5 * (i1 - 1);
- if oldback <> newback then begin
- dc := getdc(hwindow);
- frameit(dc);
- releasedc(hwindow, dc);
- end;
- end;
- end;
- end;
-
- constructor tqueenwindow.init(aparent : pwindowsobject; aname : pchar);
- begin
- twindow.init(aparent, appname);
- with attr do begin
- x := 40; y := 30;
- w := 700; h := 500;
- style := ws_caption or ws_sysmenu or ws_minimizebox;
- end;
- buttondown := false;
- setrect(cardsize, 0, 0, 71, 96);
- move[3] := 0;
- level := 1;
- back := 1;
- messagebox(hwindow, '"addictions" vol.I - written by Steven', 'Queen', mb_ok);
- newgame;
- end;
-
- procedure tqueenwindow.defcommandproc(var msg : tmessage);
- var pabout : pdialog;
- pdeck : pwindow;
- i1 : array[0..5] of char;
- newdeck : integer;
- begin
- if msg.wparamhi = 0 then
- case msg.wparamlo of
- 101 : newgame;
- 102 : begin
- pdeck := new(pdeckwindow, init(@self, 'Select Card Back'));
- application^.makewindow(pdeck);
- end;
- 103 : done;
- 104 : begin
- new(pabout, init(@self, 'queenabout'));
- if application^.execdialog(pabout) = id_ok then application^.done;
- end;
- else twindow.defcommandproc(msg);
- end;
- end;
-
- procedure tqueenwindow.drawbmp(dc : hdc; x, y : integer; size : trect; bitmap : hbitmap);
- var memdc : hdc;
- bm : tbitmap;
- madedc : boolean;
- begin
- if dc = 0 then begin
- dc := getdc(hwindow);
- madedc := true;
- end
- else madedc := false;
- memdc := createcompatibledc(dc);
- selectobject(memdc, bitmap);
- with size do
- bitblt(dc, x, y, right - left, bottom - top, memdc, left, top, srccopy);
- deletedc(memdc);
- if madedc then releasedc(hwindow, dc);
- end;
-
- function tqueenwindow.getclassname;
- begin
- getclassname := appname;
- end;
-
- procedure tqueenwindow.getwindowclass(var awndclass : twndclass);
- begin
- twindow.getwindowclass(awndclass);
- awndclass.hicon := loadicon(hinstance, appname);
- attr.menu := loadmenu(hinstance, appname);
- end;
-
- procedure tqueenwindow.moving;
- var i1, i2 : integer;
- dc, memdc : hdc;
- temp : array[1..2] of trect;
- temp2 : trect;
- begin
- with game[move[3]] do begin
- dc := getdc(hwindow);
- memdc := createcompatibledc(dc);
- selectobject(memdc, card[deck]);
- setrect(newrect, newgx, newgy, newgx + 71, newgy + 96);
- if intersectrect(temp[1], newrect, pos[row, col].rects) = 0 then begin
- setrect(temp[1], gx, gy, gx + 71, gy + 96);
- setrect(temp[2], gx, gy, gx + 71, gy + 96);
- end
- else begin
- temp[2] := temp[1];
- if gx < newgx then begin
- temp[1].left := gx;
- temp[1].right := newgx;
- temp[2].left := gx;
- end;
- if gx > newgx then begin
- temp[1].left := newgx + 71;
- temp[1].right := gx + 71;
- temp[2].right := gx + 71;
- end;
- if gy < newgy then begin
- temp[2].top := gy;
- temp[2].bottom := newgy;
- end;
- if gy > newgy then begin
- temp[2].top := newgy + 96;
- temp[2].bottom := gy + 96;
- end;
- if not fin then begin
- if gx = newgx then temp[1].right := newgx;
- if gy = newgy then temp[2].bottom := newgy;
- end;
- end;
- for i2 := 1 to 2 do
- with temp[i2] do
- bitblt(dc, left, top, right - left, bottom - top, memdc, 0, 0, whiteness);
- deletedc(memdc);
- releasedc(hwindow, dc);
- for i1 := 1 to 53 do
- if (i1 <> move[3]) and game[i1].onscreen then
- if intersectrect(temp[1], pos[game[i1].row, game[i1].col].rects,
- pos[row, col].rects) <> 0 then begin
- temp[2] := temp[1];
- if (gx < newgx) and (newgx < temp[1].right) then
- temp[1].right := newgx;
- if (gx > newgx) and (newgx + 71 > temp[1].left) then
- temp[1].left := newgx + 71;
- if (gy < newgy) and (newgy < temp[2].bottom) then
- temp[2].bottom := newgy;
- if (gy > newgy) and (newgy + 96 > temp[2].top) then
- temp[2].top := newgy + 96;
- if not fin then begin
- if gx = newgx then temp[1].right := newgx;
- if gy = newgy then temp[2].bottom := newgy;
- end;
- for i2 := 1 to 2 do begin
- offsetrect(temp[i2], - game[i1].gx, - game[i1].gy);
- if not game[i1].opened then
- drawbmp(dc, game[i1].gx + temp[i2].left, game[i1].gy +
- temp[i2].top, temp[i2], face[back])
- else drawbmp(dc, game[i1].gx + temp[i2].left, game[i1].gy +
- temp[i2].top, temp[i2], card[game[i1].deck]);
- end;
- end;
- end;
- end;
-
- procedure tqueenwindow.newgame;
- var i1, ran : 1..53;
- ro, co : integer;
- begin
- i1 := 1;
- for ro := 1 to 7 do
- for co := 1 to ro do
- with game[i1] do begin
- row := ro; col := co;
- with pos[row, col] do begin
- num := i1;
- px := round(350 - 76 * (row / 2 - col + 1));
- py := (ro - 1) * 30 + 10;
- gx := px; gy := py;
- setrect(rects, px, py, px + 71, py + 96);
- end;
- i1 := i1 + 1;
- end;
- with game[53] do begin
- row := 10; col := 10; gx := 15; gy := 310; deck := 53;
- with pos[row, col] do begin
- px := gx; py := gy; num := 53;
- setrect(pos[row, col].rects, px, py, px + 71, py + 96);
- end;
- end;
- randomize;
- game[1].deck := 38;
- game[1].canopen := true;
- game[1].opened := true;
- game[53].canopen := true;
- game[53].canmove := false;
- game[53].opened := true;
- game[53].onscreen := true;
- for i1 := 1 to 52 do begin
- dealt[i1] := false;
- game[i1].canmove := false;
- game[i1].onscreen := true;
- if i1 > 28 then game[i1].onscreen := false;
- end;
- dealt[38] := true;
- for i1 := 2 to 52 do begin
- repeat
- ran := random(52) + 1
- until dealt[ran] = false;
- game[i1].deck := ran;
- game[i1].canopen := false;
- game[i1].opened := false;
- dealt[ran] := true;
- end;
- for i1 := 22 to 28 do begin
- game[i1].canopen := true;
- game[i1].canmove := true;
- game[i1].opened := true;
- end;
- card[53] := loadbitmap(hinstance, pchar(back + 52));
- invalidaterect(hwindow, nil, true);
- for i1 := 29 to 52 do
- with game[i1] do begin
- row := 11; col := i1 - 28;
- with pos[row, col] do begin
- num := i1;
- px := round(500 / 23 * (col - 1)) + 100;
- py := 310;
- gx := px; gy := py;
- setrect(pos[row, col].rects, px, py, px + 71, py + 96);
- end;
- end;
- end;
-
- procedure tqueenwindow.paint(dc : hdc; var ps : tpaintstruct);
- var i1 : 1..53;
- begin
- for i1 := 1 to 53 do
- with game[i1] do
- if onscreen then begin
- if not opened then drawbmp(dc, gx, gy, cardsize, face[back])
- else drawbmp(dc, gx, gy, cardsize, card[deck]);
- end;
- end;
-
- procedure tqueenwindow.setupwindow;
- var i1 : 1..52;
- begin
- twindow.setupwindow;
- for i1 := 1 to 52 do
- card[i1] := loadbitmap(hinstance, pchar(i1));
- for i1 := 1 to 10 do
- face[i1] := loadbitmap(hinstance, pchar(i1 + 52));
- card[53] := face[back];
- end;
-
- procedure tqueenwindow.wmdestroy(var msg : tmessage);
- var i1 : 1..53;
- begin
- for i1 := 1 to 53 do
- deleteobject(card[i1]);
- for i1 := 1 to 10 do
- deleteobject(face[i1]);
- twindow.wmdestroy(msg);
- end;
-
- procedure tqueenwindow.wmlbuttondown(var msg : tmessage);
- var i1, co : 1..53;
- temp : trect;
- begin
- if not game[1].onscreen then begin
- buttondown := true;
- killtimer(hwindow, 1);
- for i1 := 1 to 53 do
- game[i1].onscreen := false;
- invalidaterect(hwindow, nil, true);
- level := level + 1;
- if messagebox(hwindow, 'Do you want another one ?', 'You did it !',
- mb_yesno or mb_iconexclamation) = id_yes then newgame
- else done;
- end;
- if not buttondown then begin
- fin := false;
- move[3] := 0;
- for i1 := 1 to 53 do begin
- with game[i1] do
- if ptinrect(pos[row, col].rects, tpoint(msg.lparam)) and onscreen then
- move[3] := i1;
- end;
- if move[3] = 53 then buttondown := true;
- if move[3] <> 0 then
- with game[move[3]] do begin
- move[1] := msg.lparamlo - gx;
- move[2] := msg.lparamhi - gy;
- setrect(temp, gx, gy, gx + 71, gy + 96);
- if opened and ((Deck mod 13) = 0) then begin
- buttondown := true;
- onscreen := false;
- end;
- if (canopen and not opened) and (move[3] < 29) then begin
- opened := true;
- buttondown := true;
- end;
- end;
- end;
- end;
-
- procedure tqueenwindow.wmlbuttonup(var msg : tmessage);
- var i1, ro, co : 1..52;
- temp : trect;
- only1, cancel, head, tail : integer;
- cancancel : boolean;
- begin
- if buttondown and (move[3] <> 0) then begin
- if move[3] = 53 then begin
- if not game[52].opened then begin
- i1 := 28;
- repeat
- i1 := i1 + 1;
- with game[i1] do
- if not opened then begin
- canopen := true;
- opened := true;
- canmove := true;
- onscreen := true;
- invalidaterect(hwindow, @pos[row, col].rects, true);
- i1 := 52;
- end;
- until i1 > 51;
- end;
- if game[52].opened then begin
- card[53] := loadbitmap(hinstance, pchar(63));
- invalidaterect(hwindow, @pos[10, 10].rects, true);
- end;
- end
- else with game[move[3]] do begin
- only1 := 0;
- newgx := gx; newgy := gy;
- fin := true;
- moving;
- if moved then begin
- for i1 := 1 to 52 do
- if intersectrect(temp, pos[game[i1].row, game[i1].col].rects,
- pos[row, col].rects) <> 0 then
- if ((deck mod 13) + (game[i1].deck mod 13)) = 13 then
- with game[i1] do begin
- if i1 = 1 then begin
- if (move[3] = 2) and not game[3].onscreen then
- game[1].canmove := true;
- if (move[3] = 3) and not game[2].onscreen then
- game[1].canmove := true;
- end;
- if opened and onscreen then begin
- if canmove then begin
- only1 := only1 + 1;
- cancel := i1;
- end
- else if (move[3] > 28) and (i1 > 28) then begin
- cancancel := true;
- if abs(i1 - move[3]) = 1 then begin
- only1 := only1 + 1;
- cancel := i1;
- end
- else begin
- for co := 1 to abs(i1 - move[3]) - 1 do begin
- if (i1 > move[3]) and game[move[3] + co].onscreen then
- cancancel := false;
- if (i1 < move[3]) and game [i1 + co].onscreen then
- cancancel := false;
- end;
- if cancancel then begin
- only1 := only1 + 1;
- cancel := i1;
- end;
- end;
- end;
- end;
- end;
- if only1 = 1 then with game[cancel] do begin
- onscreen := false;
- game[move[3]].onscreen := false;
- invalidaterect(hwindow, @pos[row, col].rects, true);
- end;
- end;
- for ro := 1 to 6 do
- for co := 1 to ro do
- if (not game[pos[ro + 1, co].num].onscreen) and (not game[pos[ro + 1,
- co + 1].num].onscreen) then
- with game[pos[ro, co].num] do begin
- canopen := true;
- canmove := true;
- end;
- gx := pos[row, col].px; gy := pos[row, col].py;
- newgx := gx; newgy := gy;
- setrect(pos[row, col].rects, gx, gy, gx + 71, gy + 96);
- if only1 <> 1 then invalidaterect(hwindow, @pos[row, col].rects, true);
- end;
- end;
- head := 1;
- tail := 29;
- for i1 := 29 to 52 do begin
- game[i1].canmove := false;
- if game[i1].onscreen and (head = 1) then head := i1;
- if game[i1].onscreen and game[i1].opened then tail := i1;
- end;
- if head = 1 then head := 29;
- game[head].canmove := true;
- game[tail].canmove := true;
- i1 := 1;
- repeat
- tail := 1;
- with pos[11, i1] do
- if not game[num].onscreen and game[num].opened then begin
- game[55] := game[num];
- head := i1;
- repeat
- with pos[11, head + 1] do begin
- game[54] := game[num];
- game[num].gx := game[55].gx;
- game[num].gy := game[55].gy;
- game[num].col := game[55].col;
- pos[11, head].num := num;
- game[55] := game[54];
- if (head = 1) and game[pos[11, 1].num].onscreen then
- invalidaterect(hwindow, @pos[11, 1].rects, true);
- if game[num].onscreen then invalidaterect(hwindow, @rects, true);
- end;
- head := head + 1;
- until (pos[11, head].num > 51) or (head > 23);
- if (i1 = 1) and not game[num].onscreen then tail := 0;
- if (i1 > 1) and not game[52].opened then tail := 0;
- end;
- i1 := i1 + tail;
- until (i1 > 22) or (pos[11, i1].num = 52);
- if not game[1].onscreen then begin
- if move[3] = 1 then move[1] := cancel
- else move[1] := move[3];
- if settimer(hwindow, 1, 1, nil) = 0 then begin
- messagebox(hwindow, 'No timers left !', 'Error', mb_ok);
- halt(1);
- end;
- end;
- move[3] := 0;
- buttondown := false;
- moved := false;
- end;
-
- procedure tqueenwindow.wmmousemove(var msg : tmessage);
- var x, y, head, tail : integer;
- begin
- if move[3] <> 0 then
- with game[move[3]] do
- if canmove then begin
- buttondown := true;
- moved := true;
- x := msg.lparamlo - gx - move[1];
- y := msg.lparamhi - gy - move[2];
- newgx := gx + x; newgy := gy + y;
- moving;
- offsetrect(pos[row, col].rects, x, y);
- gx := newgx; gy := newgy;
- drawbmp(0, gx, gy, cardsize, card[deck]);
- end;
- end;
-
- procedure tqueenwindow.wmrbuttondown(var msg : tmessage);
- var i1 : integer;
- begin
- if not game[1].onscreen then begin
- killtimer(hwindow, 1);
- for i1 := 1 to 53 do
- game[i1].onscreen := false;
- invalidaterect(hwindow, nil, true);
- level := level + 1;
- if messagebox(hwindow, 'Do you want another one ?', 'You did it !',
- mb_yesno or mb_iconexclamation) = id_yes then newgame
- else done;
- end
- else newgame;
- end;
-
- procedure tqueenwindow.wmtimer(var msg : tmessage);
- var i1, x, y : integer;
- angle : real;
- procedure chase(i2, x, y :integer);
- begin
- with game[i2] do begin
- if (gx < 5) or (gx > 625) then canopen := not canopen;
- if canopen then gx := gx - 5 * x
- else gx := gx + 5 * x;
- if (gy < 5) or (gy > 375) then canmove := not canmove;
- if canmove then gy := gy - 5 * x
- else gy := gy + 5 * x;
- drawbmp(0, gx, gy, cardsize, card[deck]);
- end;
- end;
- begin
- if level = 4 then level := 1;
- case level of
- 1 : for i1 := 1 to 50 do begin
- chase(1, 1, 1);
- chase(move[1], 1, 1);
- end;
- 2 : for i1 := 1 to 50 do begin
- x := random(21) * 35;
- y := random(11) * 48;
- case random(3) of
- 0 : drawbmp(0, x, y, cardsize, card[38]);
- 1 : drawbmp(0, x, y, cardsize, card[game[move[1]].deck]);
- 2, 3 : drawbmp(0, x, y, cardsize, face[back]);
- end;
- end;
- 3 : for i1 := 0 to 72 do begin
- angle := i1 * pi /36;
- x := round(cos(angle) * (1 - sin(angle)) * 150);
- y := 47 - round(sin(angle) * (1 - sin(angle)) * 150);
- drawbmp(0, 315 + x, y, cardsize, card[38]);
- drawbmp(0, 315 - x, y, cardsize, card[game[move[1]].deck]);
- end;
- end;
- end;
-
- procedure tmyapplication.initmainwindow;
- begin
- mainwindow := new(pqueenwindow, init(nil, appname));
- end;
-
- var myapp : tmyapplication;
- begin
- myapp.init(appname);
- myapp.run;
- myapp.done;
- end.
-