--- /dev/null
+import "ecere"
+
+#define NUMLEVELS 11
+#define DIMX 16
+#define DIMY 16
+#define MAXTIME (5*60)
+#define TIME2 (4*60)
+#define TIME1 (2*60)
+#define TIMEBAR gray
+#define TIMEFILL darkBlue
+
+#define NOTHING 0
+#define PLAYER 1
+#define BOMB5 2
+#define BOMB3 3
+#define BOMB1 4
+#define BOMBD 5
+#define DESACTIV 6
+#define BLOCK 7
+
+#define STATE_MENU 0
+#define STATE_GAME 1
+#define STATE_CREDITS 2
+#define STATE_ENDSCREEN 3
+#define STATE_PASSWORD 4
+
+static char passwords[NUMLEVELS+1][5] =
+{
+ "","1111","2222","3333","4444","5555","6666",
+ "7777","8888","9999","AAAA","BBBB"
+};
+
+BombApp app;
+
+class Bomb : Window
+{
+ borderStyle = sizable, hasMaximize = true, hasMinimize = true, hasClose = true;
+ text = "Bomb Squad", clientSize = Size { 640,400 };
+
+ bool fullScreen;
+ char board[DIMY][DIMX];
+
+ Bitmap gfx[8];
+ Bitmap mainBitmap {};
+ Bitmap credits {};
+ Bitmap endScreen {};
+ Bitmap password {};
+
+ Size mapSize;
+ Point player;
+ double startTime, secPassed;
+ int level;
+ int state;
+
+ bool DelayExpired()
+ {
+ int x,y, b;
+ double currentTime = GetTime();
+ secPassed = currentTime - startTime;
+ if(secPassed >= TIME2)b=BOMB1;
+ else if(secPassed >= TIME1)b=BOMB3;
+ else b=BOMB5;
+
+ for(y=0; y<DIMY; y++)
+ for(x=0; x<DIMX; x++)
+ if((board[y][x]==BOMB1)||(board[y][x]==BOMB3)||(board[y][x]==BOMB5))
+ board[y][x]=(byte)b;
+
+ if(secPassed >= MAXTIME)
+ {
+ state = STATE_MENU;
+ SetPalette(true);
+ timer.Stop();
+ }
+ Update(null);
+ return true;
+ }
+ Timer timer
+ {
+ this, Seconds { 1 }, DelayExpired = DelayExpired
+ };
+ EditBox passEdit
+ {
+ this, textHorzScroll = true, text = "Password",
+ anchor = Anchor { left = 0.03, top = 0.05, right = 0.84, bottom = 0.80 },
+ autoCreate = false
+ };
+ Bitmap buffer {};
+
+ bool IsDone()
+ {
+ bool lost = false;
+ int x,y;
+ for(y=0; y<DIMY; y++)
+ for(x=0; x<DIMX; x++)
+ if((board[y][x]==BOMB1)||(board[y][x]==BOMB3)||(board[y][x]==BOMB5))
+ lost = true;
+ return !lost;
+ }
+
+ void SetPalette(bool flag)
+ {
+ ColorAlpha * palette = null;
+ switch(state)
+ {
+ case STATE_GAME: palette = LoadPalette(":nothing.pcx", null); break;
+ case STATE_MENU: palette = LoadPalette(":max3.pcx", null); break;
+ case STATE_CREDITS: palette = LoadPalette(":3.pcx", null); break;
+ case STATE_ENDSCREEN: palette = LoadPalette(":max3.pcx", null); break;
+ }
+ CopyBytesBy4(buffer.palette, palette, 256);
+ display.SetPalette(palette, flag);
+ delete palette;
+ }
+
+ void LoadLevel(int level)
+ {
+ File f;
+ char map[80];
+
+ // Start the game
+ this.level = level;
+ state = STATE_GAME;
+ timer.Start();
+ startTime = GetTime();
+ sprintf(map,":map%d.dat",level);
+
+ f = FileOpen(map, read);
+ if(f)
+ {
+ int x,y;
+ for(y=0; y<DIMY; y++)
+ for(x=0; x<DIMX; x++)
+ {
+ char ch;
+ f.Getc(&ch);
+ board[y][x] = ch;
+
+ if(board[y][x]==PLAYER)
+ {
+ player = Point{x,y};
+ board[y][x]=NOTHING;
+ }
+ }
+ delete f;
+ }
+
+ DelayExpired();
+ SetPalette(true);
+ }
+
+ bool OnStateChange(WindowState state, Modifiers mods)
+ {
+ if(state == maximized && (Key)mods == hotKey)
+ {
+ app.fullScreen = true;
+ app.resolution = res320x200;
+ app.pixelFormat = pixelFormat8;
+ borderStyle = none;
+ anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
+ return false;
+ }
+ return true;
+ }
+
+ bool OnLoadGraphics()
+ {
+ int c;
+ endScreen.Load(":max3.pcx", null, null);
+ mainBitmap.Load(":max3.pcx", null, null);
+ credits.Load(":3.pcx", null, null);
+ password.Load(":password.pcx", null, null);
+
+ for(c = 0; c<8; c++)
+ gfx[c] = Bitmap {};
+ gfx[NOTHING].Load(":nothing.pcx", null, null);
+ gfx[PLAYER].Load(":player.pcx", null, null);
+ gfx[BOMB5].Load(":bomb.pcx", null, null);
+ gfx[BOMB3].Load(":deadeac.pcx", null, null);
+ gfx[BOMB1].Load(":deadeac.pcx", null, null);
+ gfx[BOMBD].Load(":deacbomb.pcx", null, null);
+ gfx[DESACTIV].Load(":desactiv.pcx", null, null);
+ gfx[BLOCK].Load(":block.pcx", null, null);
+
+ mapSize.w = gfx[0].width;
+ mapSize.h = gfx[0].height;
+
+ buffer.AllocateDD(displaySystem, 320, 200);
+
+ SetPalette(true);
+ return true;
+ }
+
+ void OnUnloadGraphics()
+ {
+ int c;
+
+ for(c=0; c<8; c++)
+ delete gfx[c];
+ mainBitmap.Free();
+ credits.Free();
+ endScreen.Free();
+ password.Free();
+ buffer.Free();
+ }
+
+ void OnRedraw(Surface surface2)
+ {
+ Surface surface = buffer.GetSurface(0,0, null);
+
+ surface.SetBackground(black);
+ surface.Clear(colorBuffer);
+ switch(state)
+ {
+ case STATE_GAME:
+ {
+ int x,y;
+ int width;
+ int offX = (320 - mapSize.w * DIMX) / 2;
+ int offY = (200 - mapSize.h * DIMY - 20) / 2;
+
+ for(y=0; y<DIMY; y++)
+ for(x=0; x<DIMX; x++)
+ surface.Blit(gfx[board[y][x]],
+ offX + x*mapSize.w, offY + y*mapSize.h, 0,0,
+ mapSize.w,mapSize.h);
+ surface.Blit(gfx[PLAYER],
+ offX + player.x*mapSize.w, offY + player.y*mapSize.h,
+ 0,0,mapSize.w,mapSize.h);
+
+ surface.SetForeground(TIMEBAR);
+ surface.Rectangle(0,buffer.height - 20,buffer.width-1,buffer.height-1);
+ width = (int)((buffer.width - 2)*(MAXTIME-secPassed)/MAXTIME);
+ surface.SetBackground(TIMEFILL);
+ surface.Area(1,buffer.height - 19,width,buffer.height - 2);
+ break;
+ }
+ case STATE_MENU:
+ surface.Blit(mainBitmap, 0,0, 0,0, mainBitmap.width,mainBitmap.height);
+ break;
+ case STATE_CREDITS:
+ surface.Blit(credits, 0,0, 0,0, credits.width,credits.height);
+ break;
+ case STATE_ENDSCREEN:
+ surface.Blit(endScreen, 0,0, 0,0, endScreen.width,endScreen.height);
+ break;
+ case STATE_PASSWORD:
+ surface.Blit(password, 0,0,0,0,password.width, password.height);
+ break;
+ }
+
+ delete surface;
+ surface2.Stretch(buffer, 0,0, 0,0, clientSize.w, clientSize.h,
+ buffer.width, buffer.height);
+ }
+
+ bool OnKeyDown(Key key, unichar character)
+ {
+ if(state == STATE_PASSWORD)
+ {
+ if(key == enter)
+ {
+ int l;
+ char * pwd = passEdit.contents;
+ for(l=1; l<=NUMLEVELS; l++)
+ if(!strcmpi(pwd,passwords[l]))
+ {
+ char string[80];
+ sprintf(string, "Wrapping to level %d...",l);
+ MessageBox { text = "Password Accepted", contents = string }.Modal();
+ LoadLevel(l);
+ break;
+ }
+ }
+ else if(key != escape)
+ return true;
+
+ passEdit.Destroy(0);
+ if(state == STATE_PASSWORD) state = STATE_MENU;
+ Update(null);
+ }
+ else if(state == STATE_MENU)
+ {
+ switch(key)
+ {
+ case s: LoadLevel(1); break;
+ case p:
+ state = STATE_PASSWORD;
+ passEdit.Create();
+ break;
+ case x: Destroy(0); return false;
+ case c: state = STATE_CREDITS; SetPalette(true); break;
+ }
+ Update(null);
+ }
+ switch(key)
+ {
+ case escape:
+ if(state == STATE_GAME)
+ timer.Stop();
+ state = STATE_MENU;
+ SetPalette(true);
+ Update(null);
+ break;
+ case altEnter:
+ fullScreen = false;
+ borderStyle = sizable, hasClose = true, hasMinimize = true, hasMaximize = true;
+ clientSize = { 640, 400 };
+ return false;
+ }
+ return true;
+ }
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ if(state == STATE_GAME)
+ {
+ int dx=0,dy=0;
+
+ switch(key)
+ {
+ case up: dy=-1; break;
+ case down: dy=1; break;
+ case left: dx=-1; break;
+ case right: dx=1; break;
+ default: return true;
+ }
+
+ if((player.x+dx<0)||(player.y+dy<0)||(player.x+dx>=DIMX)||(player.y+dy>=DIMY))
+ return true;
+
+ if(board[player.y+dy][player.x+dx]==BLOCK) return true;
+ if((board[player.y+dy][player.x+dx]==BOMB5)
+ ||(board[player.y+dy][player.x+dx]==BOMB3)
+ ||(board[player.y+dy][player.x+dx]==BOMB1)
+ ||(board[player.y+dy][player.x+dx]==BOMBD))
+ {
+ if((player.x+dx*2<0)||(player.y+dy*2<0)||(player.x+dx*2>=DIMX)||(player.y+dy*2>=DIMY))
+ return true;
+ if((board[player.y+2*dy][player.x+2*dx]!=DESACTIV)&&
+ (board[player.y+2*dy][player.x+2*dx]!=NOTHING))
+ return true;
+ if(board[player.y+dy][player.x+dx]==BOMBD)
+ board[player.y+dy][player.x+dx]=DESACTIV;
+ else
+ board[player.y+dy][player.x+dx]=NOTHING;
+ if(board[player.y+2*dy][player.x+2*dx]==DESACTIV)
+ board[player.y+2*dy][player.x+2*dx]=BOMBD;
+ else
+ {
+ int b;
+ if(secPassed >= TIME2)b=BOMB1;
+ else if(secPassed >= TIME1)b=BOMB3;
+ else b=BOMB5;
+ board[player.y+2*dy][player.x+2*dx]=(byte)b;
+ }
+ }
+
+ player.x+=dx;
+ player.y+=dy;
+
+ if(IsDone())
+ {
+ if(level == NUMLEVELS)
+ {
+ state = STATE_ENDSCREEN;
+ SetPalette(true);
+ }
+ else
+ {
+ char string[80];
+ sprintf(string, "Password to level %d is: %s",level+1,passwords[level+1]);
+ timer.Stop();
+ MessageBox { text = "Congratulations! You win!", contents = string }.Modal();
+ LoadLevel(level + 1);
+ }
+ }
+ Update(null);
+ }
+ return true;
+ }
+}
+
+class BombApp : GuiApplication
+{
+ Bomb bomb {};
+ void Main()
+ {
+ app = this;
+ GuiApplication::Main();
+ }
+}
--- /dev/null
+
+ECERE Project File
+
+Version 0.1a
+
+Target "bomb"
+
+ Configurations
+
+ + Debug
+
+ Compiler Options
+
+ Intermediate Directory = Debug
+ Debug = True
+ Optimize = None
+ Profile = False
+ MemoryGuard = False
+ AllWarnings = True
+ Strict Name Spaces = False
+
+ Linker Options
+
+ Target Name = bomb
+ Target Type = Executable
+ Target Directory = Debug
+ Console = False
+
+ Libraries = ecere
+
+ + MemoryGuard
+
+ Compiler Options
+
+ Intermediate Directory = MemoryGuard
+ Debug = True
+ Optimize = None
+ Profile = False
+ MemoryGuard = True
+ AllWarnings = True
+ Strict Name Spaces = False
+
+ Linker Options
+
+ Target Name = bomb
+ Target Type = Executable
+ Target Directory = MemoryGuard
+ Console = True
+
+ Libraries = ecere
+
+ + Release
+
+ Compiler Options
+
+ Intermediate Directory = Release
+ Debug = False
+ Optimize = Speed
+ Profile = False
+ MemoryGuard = False
+ AllWarnings = True
+ Strict Name Spaces = False
+
+ Linker Options
+
+ Target Name = bomb
+ Target Type = Executable
+ Target Directory = Release
+ Console = False
+
+ Libraries = ecere
+
+ Files
+
+ - bomb.ec
+
+ Resources
+
+ = data/map1.dat
+ = data/map10.dat
+ = data/map11.dat
+ = data/map2.dat
+ = data/map3.dat
+ = data/map4.dat
+ = data/map5.dat
+ = data/map6.dat
+ = data/map7.dat
+ = data/map8.dat
+ = data/map9.dat
+ = data/3.pcx
+ = data/block.pcx
+ = data/bomb.pcx
+ = data/deacbomb.pcx
+ = data/deadeac.pcx
+ = data/desactiv.pcx
+ = data/max3.pcx
+ = data/nothing.pcx
+ = data/password.pcx
+ = data/player.pcx
--- /dev/null
+/****************************************************************************
+ POKER Game Interface
+
+ Copyright (c) 2001 Jerome Jacovella-St-Louis
+ All Rights Reserved.
+
+ bet.ec - Poker Bet Window
+****************************************************************************/
+import "poker.ec"
+
+class Bet : Window
+{
+ background = activeBorder;
+ borderStyle = fixed;
+ clientSize = Size { 140, 80 };
+
+ int * thisBet;
+ Button bet
+ {
+ this,
+ text = "Bet",
+ size = Size { 40, 20 },
+ anchor = Anchor { horz = -20 };
+ hotKey = b,
+ isDefault = true;
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ int theBet = (int) strtod(edit.contents, null) * 2;
+ if(theBet > 0 && *thisBet + theBet >= currentBet)
+ {
+ *thisBet += theBet;
+ Destroy(1);
+ }
+ return true;
+ }
+ };
+ Button pass
+ {
+ this,
+ text = currentBet ? "Fold" : "Pass",
+ size = Size { 40, 20 },
+ anchor = Anchor { horz = 20 },
+ hotKey = currentBet ? f : p;
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ Destroy(0);
+ return true;
+ }
+ };
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ if(key == escape) Destroy(0);
+ return true;
+ }
+ EditBox edit { this, anchor = Anchor { top = 10 }, size = Size { 80, 20 } };
+
+ property int * thisBet { set { this.thisBet = value; } };
+
+ void OnRedraw(Surface surface)
+ {
+ surface.SetForeground(red);
+ surface.WriteTextf(0, 65, "$%.2f to you.", (currentBet - *thisBet) / 2.0);
+ }
+}
--- /dev/null
+/****************************************************************************
+ POKER Game Interface
+
+ Copyright (c) 2001 Jerome Jacovella-St-Louis
+ All Rights Reserved.
+
+ player.ec - Poker Player Window
+****************************************************************************/
+import "poker.ec"
+import "pokerUtils.ec"
+
+static char handTypes[10][20] =
+{
+ "NOTHING",
+ "ONE PAIR",
+ "TWO PAIRS",
+ "THREE OF A KIND",
+ "STRAIGHT",
+ "FLUSH",
+ "FULL HOUSE",
+ "FOUR OF A KIND",
+ "STRAIGHT FLUSH",
+ "ROYAL FLUSH"
+};
+
+class Player : Window
+{
+ borderStyle = sizable;
+
+ bool human;
+ int numUp, numDown;
+ int money;
+ int up [52];
+ int down[52];
+ int thisBet;
+ bool folded;
+ int bestHand[5];
+ int handType;
+ bool winner;
+
+ Player()
+ {
+ money = 40 * 2;
+ }
+
+ void OnRedraw(Surface surface)
+ {
+ Poker poker = (Poker)master;
+ int c;
+
+ for(c=0; c<numDown; c++)
+ {
+ poker.DrawCard(surface, c*15, 0, (human || gameOver && !folded) ? POKER_Card(down[c]) : -1);
+ }
+ POKER_HandType(bestHand);
+ for(c=0; c<numUp; c++)
+ poker.DrawCard(surface, c*15, 40, folded ? -1 : POKER_Card(up[c]));
+ if(folded)
+ {
+ surface.SetForeground(blue);
+ surface.WriteTextf(10, 130, "FOLDED");
+ }
+ else if(gameOver)
+ {
+ surface.SetForeground(red);
+ if(winner)
+ surface.WriteTextf(10, 130, "WINNER");
+ surface.SetForeground(blue);
+ surface.WriteTextf(80, 130, "%s", handTypes[handType]);
+ }
+ surface.SetForeground(white);
+ surface.WriteTextf(110, 110, "$%.2f", money / 2.0);
+ }
+}
--- /dev/null
+/****************************************************************************
+ POKER Game Interface
+
+ Copyright (c) 2001 Jerome Jacovella-St-Louis
+ All Rights Reserved.
+
+ poker.ec - Poker Main Window
+****************************************************************************/
+import "ecere"
+import "player.ec"
+import "widow.ec"
+import "bet.ec"
+
+enum PokerHand { nothing, onePair, twoPair, threeOfAKind, straight, flush, fullHouse, fourOfAKind, straightFlush, royalFlush };
+
+/*
+ROYAL FLUSH 0.0002 %
+STRAIGHT FLUSH 0.0012 %
+FOUR OF A KIND 0.0240 %
+FULL HOUSE 0.1441 %
+FLUSH 0.1967 %
+STRAIGHT 0.3532 %
+THREE OF A KIND 2.1128 %
+TWO PAIR 4.7539 %
+ONE PAIR 42.2569 %
+NOTHING 50.1570 %
+*/
+
+enum Facing { faceDown, faceUp };
+
+static int lowHand[5] = { 4*0 + 1, 4*1, 4*2, 4*3, 4*5 };
+static Player players[6];
+static int deck[52], deckIndex;
+
+static int numPlayers;
+static int numPlayersLeft;
+static char playerNames[6][20] =
+{
+ "Jerome",
+ "Adam",
+ "Jason",
+ "Bruce",
+ "Pete",
+ "Daniel"
+};
+static Pointf positions[5][6] =
+{
+ {{ .50f, .82f }, { .50f, .18f }},
+ {{ .50f, .82f }, { .18f, .18f }, { .82f, .18f}},
+ {{ .50f, .82f }, { .18f, .50f }, { .50f, .18f}, { .82f, .50f}},
+ {{ .50f, .82f }, { .18f, .50f }, { .50f, .18f}, { .82f, .50f}, { .82f, .50f}},
+ {{ .25f, .82f }, { .18f, .50f }, { .25f, .18f}, { .75f, .18f}, { .82f, .50f}, { .75f, .82f}}
+};
+
+// --- Data Used by Child Window Classes ---
+int currentBet;
+int potMoney;
+int widowNum = 0;
+int widow[52];
+bool gameOver = true;
+
+define ANTE = 1;
+
+class Poker : Window
+{
+ background = teal;
+ hasMinimize = true, hasMaximize = true, hasClose = true;
+ borderStyle = sizable;
+ text = "ECERE Poker";
+ size = Size { 800, 600 };
+
+ Bitmap bitmapCards[52];
+ Bitmap cardBack {};
+
+ Widow widowWindow { this, opacity = 0, text = "Widow", borderStyle = sizable, anchor = Anchor { left = 0.375, top = 0.34, right = 0.375, bottom = 0.34 } };
+
+ void DrawCard(Surface surface, int x, int y, int card)
+ {
+ Bitmap bitmap;
+ if(card != -1)
+ bitmap = bitmapCards[card];
+ else
+ bitmap = cardBack;
+ surface.Blit(bitmap, x, y, 0,0, bitmap.width,bitmap.height);
+ }
+
+ // --- Poker Game Flow ---
+
+ void CreatePlayers(int num)
+ {
+ int c;
+
+ numPlayers = num;
+ for (c = 0; c<numPlayers; c++)
+ {
+ char string[256];
+ Pointf pos = positions[numPlayers - 2][c];
+
+ sprintf(string, "%s (%d)", playerNames[c], c + 1);
+ players[c] = Player { this, opacity = 0, text = string, anchor = Anchor { left = pos.x - 0.175, top = pos.y - 0.16, right = 1-(pos.x + 0.175), bottom = 1-(pos.y + 0.16) } };
+ players[c].Create();
+ }
+ players[0].human = true;
+ }
+
+ void Shuffle()
+ {
+ int c;
+
+ POKER_ShuffleDeck(deck);
+ deckIndex = 0;
+ numPlayersLeft = numPlayers;
+ for(c = 0; c<numPlayers; c++)
+ {
+ players[c].numDown = players[c].numUp = 0;
+ players[c].folded = false;
+ players[c].winner = false;
+ }
+ widowNum = 0;
+ gameOver = false;
+ }
+
+ void Deal(Facing up, int howMany)
+ {
+ int c;
+ int p;
+
+ for(c = 0; c<howMany; c++)
+ for(p = 0; p<numPlayers; p++)
+ {
+ Player player = players[p];
+ if(!player.folded)
+ {
+ if(up)
+ {
+ player.up[player.numUp++] = deck[deckIndex++];
+ POKER_SortCards(player.up, player.numUp);
+ }
+ else
+ {
+ player.down[player.numDown++] = deck[deckIndex++];
+ POKER_SortCards(player.down, player.numDown);
+ }
+ }
+ }
+ Update(null);
+ }
+
+ void DealWidow(int howMany)
+ {
+ int c;
+ for(c = 0; c<howMany; c++)
+ widow[widowNum++] = deck[deckIndex++];
+ POKER_SortCards(widow, widowNum);
+ Update(null);
+ }
+
+ void Ante()
+ {
+ int c;
+ for(c = 0; c<numPlayers; c++)
+ {
+ if(players[c].money >= ANTE)
+ {
+ players[c].money -= ANTE;
+ potMoney += ANTE;
+ }
+ else
+ players[c].folded = true;
+ }
+ Update(null);
+ }
+
+ void BettingRound(int firstBet)
+ {
+ int p;
+ int numBets = 0;
+
+ if(!created) return;
+
+ if(numPlayersLeft >= 2)
+ {
+ currentBet = 0;
+ for(p = 0; p<numPlayers; p++)
+ players[p].thisBet = 0;
+
+ for(p = firstBet;; p++)
+ {
+ Player player;
+ char string[64];
+ Bet bet;
+
+ if(p == numPlayers) p = 0;
+ player = players[p];
+ if(player.folded) continue;
+
+ if(currentBet && player.thisBet == currentBet) break;
+
+ sprintf(string, "Your bet, %s?", playerNames[p]);
+ bet = Bet { parent = this, thisBet = &player.thisBet, text = string };
+ bet.Create();
+ eInstance_IncRef(bet);
+ while(bet.created)
+ {
+ app.UpdateDisplay();
+ if(!app.ProcessInput(true))
+ app.Wait();
+ }
+ eInstance_DecRef(bet);
+
+ if(!created) return;
+
+ //player.thisBet = 0;
+
+ if(player.thisBet < currentBet)
+ {
+ player.folded = true;
+ numPlayersLeft--;
+ if(numPlayersLeft < 2)
+ break;
+ numBets = 0;
+ }
+ else if(player.thisBet > currentBet)
+ {
+ currentBet = player.thisBet;
+ numBets = 0;
+ }
+ else
+ numBets++;
+ potMoney += player.thisBet;
+ player.money -= player.thisBet;
+ Update(null);
+
+ if(!currentBet && numBets >= numPlayersLeft)
+ break;
+ }
+ }
+ }
+
+ void WinMoney(int numHand, int numWidow)
+ {
+ int p;
+ int numWinners = 0;
+ int bestHand[5] = { lowHand[0], lowHand[1], lowHand[2], lowHand[3], lowHand[4] };
+
+ if(!created) return;
+
+ for(p=0; p<numPlayers; p++)
+ {
+ int cards[16];
+ int c;
+ Player player = players[p];
+
+ if(player.folded) continue;
+
+ for(c = 0;; c++)
+ {
+ if(c < player.numDown)
+ cards[c] = player.down[c];
+ else if(c - player.numDown < player.numUp)
+ cards[c] = player.up[c - player.numDown];
+ else
+ break;
+ }
+ CopyBytesBy4(player.bestHand, lowHand, 5);
+ POKER_BestHand(cards, widow, c, widowNum, numHand, numWidow, player.bestHand);
+ player.handType = POKER_HandType(player.bestHand);
+ }
+
+ for(p=0; p<numPlayers; p++)
+ {
+ int c;
+ Player player = players[p];
+ if(player.folded) continue;
+
+ switch(POKER_Compare(bestHand, player.bestHand))
+ {
+ case 0:
+ numWinners ++;
+ player.winner = true;
+ break;
+ case 1:
+ for(c=0; c<numPlayers; c++)
+ players[c].winner = false;
+ numWinners = 1;
+ CopyBytesBy4(bestHand, player.bestHand, 5);
+ player.winner = true;
+ break;
+ }
+ }
+ for(p=0; p<numPlayers; p++)
+ {
+ Player player = players[p];
+ if(player.folded) continue;
+ if(POKER_Compare(player.bestHand, bestHand) == 0)
+ player.money += potMoney / numWinners;
+ }
+ if(numWinners)
+ {
+ potMoney -= (potMoney / numWinners) * numWinners;
+ }
+ gameOver = true;
+ Update(null);
+ }
+
+ // --- Poker Games Definitions ---
+
+ /*
+ TEXAS HOLDEM - The most popular poker game in Blackhawk. A variation of 7-Card
+ Stud where every player gets dealt 2 cards face down and there is a community
+ board of 5 cards. Players Ise the 2 cards in their hand plus the 5 community
+ cards to make the best possible 5 card hand. A dealers button moves around the
+ table each hand. The player to the left of the dealer button is dealt the
+ first card. Also the person to the left of the button has to post a blind.
+ There is a betting round after the players receive their first 2 cards. Then the
+ dealer places 3 cards on the board (the flop) and there is a betting round. Then
+ the dealer places another card on the board (the turn) and there is another
+ betting round. Then the dealer places the final card (the river) on the board
+ and there is a final betting round. Games may have 1 blind or 2 blinds. Games
+ vary from $2-5 betting to straight $5 betting.
+ */
+ void TexasHoldem()
+ {
+ Shuffle();
+ Ante();
+ Deal(faceDown, 2);
+ BettingRound(0);
+ DealWidow(3);
+ BettingRound(0);
+ DealWidow(1);
+ BettingRound(0);
+ DealWidow(1);
+ BettingRound(0);
+ WinMoney(2, 5);
+ }
+
+ /*
+ OMAHA - A games similar to Texas Holdem except the players are dealt 4 cards
+ face down. There is a board of 5 community cards and you must Ise 2 cards out
+ of your hand to make the best possible hand. The game may be played straight
+ high or high/lowHand. There is a dealer button that moves around the table each
+ hand and the player that has the dealers button may choose to play the game
+ straight high or high/lowHand. The player to the left of the dealer button has
+ to post a small blind of $1 and the person to his/her left has to post the
+ large blind of $2. To qualify for a lowHand hand, the player must have 5 cards
+ that are 8 or lowHander. There is a betting round after the players receive their
+ 4 cards. Then the dealer places 3 cards on the board (the flop). After the
+ betting round, the dealer places another card on the board (the turn) and there
+ is another betting round. Then the dealer places the last card (the river) on
+ the board and there is a final betting round. The betting limits are Isually
+ $2-$5.
+ */
+ void OmahaHoldem()
+ {
+ Shuffle();
+ Ante();
+ Deal(faceDown, 4);
+ BettingRound(0);
+ DealWidow(3);
+ BettingRound(0);
+ DealWidow(1);
+ BettingRound(0);
+ DealWidow(1);
+ BettingRound(0);
+ WinMoney(2, 3);
+ }
+
+ void SevenCardStud()
+ {
+ Shuffle();
+ Ante();
+ Deal(faceDown, 2);
+ Deal(faceUp, 1);
+ BettingRound(0);
+ Deal(faceUp, 1);
+ BettingRound(0);
+ Deal(faceUp, 1);
+ BettingRound(0);
+ Deal(faceUp, 1);
+ BettingRound(0);
+ Deal(faceDown, 1);
+ BettingRound(0);
+ WinMoney(5, 0);
+ }
+
+ // --- Poker Window Class ---
+ bool OnLoadGraphics()
+ {
+ Bitmap ptrCardLoad {};
+ if(ptrCardLoad.Load(":cards.pcx",null,null))
+ {
+ int i;
+ cardBack.LoadT(":ecereCard.bmp",null,displaySystem);
+
+ for(i = 0; i < 52; i++)
+ {
+ bitmapCards[i] = Bitmap {};
+ bitmapCards[i].Allocate(null,ptrCardLoad.width, ptrCardLoad.height/52,0,pixelFormat8,true);
+ CopyBytesBy4(bitmapCards[i].palette, ptrCardLoad.palette, 256);
+ bitmapCards[i].Grab(ptrCardLoad,0,(ptrCardLoad.height/52)*i);
+ bitmapCards[i].transparent = true;
+ bitmapCards[i].MakeDD(displaySystem);
+ }
+ }
+ delete ptrCardLoad;
+ return true;
+ }
+
+ void OnUnloadGraphics()
+ {
+ int i;
+ for(i=0;i<52;i++)
+ bitmapCards[i].Free();
+ cardBack.Free();
+ }
+
+ bool OnPostCreate()
+ {
+ potMoney = 0;
+ CreatePlayers(6);
+ return true;
+ }
+
+ bool OnClose(bool parentClosing)
+ {
+ if(MessageBox { type = yesNo, text = "Exit", contents = "Quit?" }.Modal() == yes)
+ return true;
+ return false;
+ }
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ if(!gameOver) return false;
+ switch(key)
+ {
+ case f1: TexasHoldem(); break;
+ case f2: OmahaHoldem(); break;
+ case f3: SevenCardStud(); break;
+ }
+ return true;
+ }
+}
+
+PokerApp app;
+
+class PokerApp : GuiApplication
+{
+ Poker { };
+ appName = "Poker Master";
+
+ bool Init()
+ {
+ int c;
+ // Initialize Card Deck
+ RandomSeed((int)(GetTime() * 1000));
+ for(c = 0; c<52; c++)
+ deck[c] = c;
+
+ app = this;
+ return true;
+ }
+}
--- /dev/null
+
+ECERE Project File
+
+Version 0a
+
+Target "poker"
+
+ Compiler Options
+
+ Intermediate Directory = obj
+ Debug = True
+ Optimize = False
+ Profile = False
+ AllWarnings = True
+
+ Linker Options
+
+ Target Name = poker
+ Target Type = Executable
+ Console = False
+
+ Libraries = ecere
+
+ Files
+
+ - bet.ec
+ - player.ec
+ - poker.ec
+ - pokerutils.ec
+ - widow.ec
+
+ Resources
+
+ = data/ecereCard.bmp
+ = data/cards.pcx
--- /dev/null
+/****************************************************************************
+ POKER Game Interface
+
+ Copyright (c) 2001 Jerome Jacovella-St-Louis
+ All Rights Reserved.
+
+ pokerutils.c - Poker Backend Utilities
+****************************************************************************/
+import "poker.ec"
+
+// --- Data ---
+
+static int handsRests[10] = { 5, 3, 1, 2, 0, 0, 0, 1, 0, 0 };
+
+// { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
+// { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
+// { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
+// { 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A }
+
+// --- Static Utilities ---
+
+static int Compare(const int * a, const int * b)
+{
+ if(*a > *b) return 1; else if(*a < *b) return -1; else return 0;
+}
+
+static bool POKER_Straight(int cards[5])
+{
+ int c;
+ for(c = 1; c<5; c++)
+ if((cards[c] / 4 != cards[c-1] / 4 + 1) && !(cards[c - 1] / 4 == 12 && cards[c] / 4 == 0))
+ return false;
+ return true;
+}
+
+static bool POKER_Flush(int cards[5])
+{
+ int c;
+ for(c = 1; c<5; c++)
+ if(cards[c] % 4 != cards[0] % 4)
+ return false;
+ return true;
+}
+
+static bool POKER_Same(int cards[5], int howMany, int what[2], int rest[3])
+{
+ int c;
+ int card;
+ int numPairs = 0;
+
+ for(card = 0; card<13; card++)
+ {
+ int num = 0;
+ for(c = 0; c < 5; c++)
+ {
+ if(cards[c] / 4 == card)
+ num++;
+ }
+ if(num == howMany)
+ {
+ what[numPairs++] = card;
+ }
+ }
+ if(numPairs)
+ {
+ int d;
+ qsort(what, numPairs, sizeof(int), Compare);
+ for(d = 0, c = 0; c<5; c++)
+ {
+ int w;
+ for(w = 0; w < numPairs; w++)
+ if(cards[c] / 4 == what[w])
+ break;
+ if(w == numPairs)
+ rest[d++] = cards[c];
+ }
+ }
+ return numPairs;
+}
+
+// --- External Functions ---
+
+void POKER_SortCards(int * cards, int numCards)
+{
+ qsort(cards, numCards, sizeof(int), Compare);
+}
+
+int POKER_Card(int card)
+{
+ if(card / 4 == 12)
+ card -= 13 * 4;
+ card += 4;
+ return card;
+}
+
+void POKER_ShuffleDeck(int deck[52])
+{
+ int t;
+ int count;
+
+ count = GetRandom(1000, 2000);
+ for(t = 0; t<count; t++)
+ {
+ // cut the deck in 2
+ int cuts[2][52];
+ int numCut[2];
+ int indexCut[2] = {0,0};
+ int cut = GetRandom(13, 39);
+ int c;
+
+ for(c = 0; c<cut; c++)
+ cuts[0][c] = deck[c];
+ for(c = cut; c<52; c++)
+ cuts[1][c - cut] = deck[c];
+
+ numCut[0] = cut;
+ numCut[1] = 52 - cut;
+
+ // Mix the cards
+ for(c = 0; c<52; c++)
+ {
+ int whichCut;
+
+ if(indexCut[0] < numCut[0] && indexCut[1] < numCut[1])
+ whichCut = GetRandom(0,1);
+ else if(indexCut[0] < numCut[0])
+ whichCut = 0;
+ else if(indexCut[1] < numCut[1])
+ whichCut = 1;
+
+ deck[c] = cuts[whichCut][indexCut[whichCut]++];
+ }
+ }
+}
+
+PokerHand POKER_HandType(int cards[5])
+{
+ bool flush, straight;
+ int numPairs, numTris, numQuads;
+ int rest[5];
+ int pairs[2], tris, quads;
+
+ /*** DETERMINE HAND TYPE ***/
+ flush = POKER_Flush(cards);
+ straight = POKER_Straight(cards);
+ numPairs = POKER_Same(cards, 2, pairs, rest);
+ numTris = POKER_Same(cards, 3, &tris, rest);
+ numQuads = POKER_Same(cards, 4, &quads, rest);
+
+ if(straight && flush)
+ {
+ if(cards[4] / 4 == 12)
+ return royalFlush;
+ else
+ return straightFlush;
+ }
+ else if(numQuads)
+ return fourOfAKind;
+ else if(numPairs && numTris)
+ return fullHouse;
+ else if(flush)
+ return PokerHand::flush;
+ else if(straight)
+ return PokerHand::straight;
+ else if(numTris)
+ return threeOfAKind;
+ else if(numPairs == 2)
+ return twoPair;
+ else if(numPairs)
+ return onePair;
+ else
+ return nothing;
+}
+
+int POKER_Compare(int cards1[5], int cards2[5])
+{
+ bool flush[2], straight[2];
+ int numPairs[2], numTris[2], numQuads[2];
+ int * cards;
+
+ int rest[2][5];
+ int pairs[2][2], tris[2], quads[2];
+ PokerHand handType[2];
+ int h;
+ int c;
+ int numRest[2];
+
+ int winner = 0;
+
+ for(h = 0; h<2; h++)
+ {
+ cards = (h == 0) ? cards1 : cards2;
+
+ /*** DETERMINE HAND TYPE ***/
+ flush[h] = POKER_Flush(cards);
+ straight[h] = POKER_Straight(cards);
+ numPairs[h] = POKER_Same(cards, 2, pairs[h], rest[h]);
+ numTris[h] = POKER_Same(cards, 3, &tris[h], rest[h]);
+ numQuads[h] = POKER_Same(cards, 4, &quads[h], rest[h]);
+
+ if(straight[h] && flush[h])
+ {
+ if(cards[4] / 4 == 12)
+ handType[h] = royalFlush;
+ else
+ handType[h] = straightFlush;
+ }
+ else if(numQuads[h])
+ handType[h] = fourOfAKind;
+ else if(numPairs[h] && numTris[h])
+ handType[h] = fullHouse;
+ else if(flush[h])
+ handType[h] = PokerHand::flush;
+ else if(straight[h])
+ handType[h] = PokerHand::straight;
+ else if(numTris[h])
+ handType[h] = threeOfAKind;
+ else if(numPairs[h] == 2)
+ handType[h] = twoPair;
+ else if(numPairs[h])
+ handType[h] = onePair;
+ else
+ {
+ handType[h] = nothing;
+ CopyBytesBy4(rest[h], cards, 5);
+ }
+ numRest[h] = handsRests[handType[h]];
+ }
+
+ /*** DETERMINE WINNING HAND ***/
+ if(handType[1] > handType[0])
+ winner = 1;
+ else if(handType[0] > handType[1])
+ winner = -1;
+ else
+ {
+ switch(handType[0])
+ {
+ case straightFlush:
+ if(cards2[4] / 4 > cards1[4] / 4)
+ winner = 1;
+ else if(cards1[4] / 4> cards2[4] / 4)
+ winner = -1;
+ break;
+ case fourOfAKind:
+ if(quads[1] > quads[0] )
+ winner = 1;
+ else if(quads[0] > quads[1])
+ winner = -1;
+ break;
+ case fullHouse:
+ if(tris[1] > tris[0] )
+ winner = 1;
+ else if(tris[0] > tris[1])
+ winner = -1;
+ else if(pairs[1][0] > pairs[0][0])
+ winner = 1;
+ else if(pairs[0][0] > pairs[1][0])
+ winner = -1;
+ break;
+ case PokerHand::flush:
+ for(c = 4; c>=0; c--)
+ {
+ if(cards2[c] / 4 > cards1[c] / 4)
+ {
+ winner = 1;
+ break;
+ }
+ else if(cards1[c] / 4 > cards2[c] / 4)
+ {
+ winner = -1;
+ break;
+ }
+ }
+ break;
+ case PokerHand::straight:
+ if(cards2[4] / 4> cards1[4] / 4)
+ winner = 1;
+ else if(cards1[4] / 4> cards2[4] / 4)
+ winner = -1;
+ break;
+ case threeOfAKind:
+ if(tris[1] > tris[0] )
+ winner = 1;
+ else if(tris[0] > tris[1])
+ winner = -1;
+ break;
+ case twoPair:
+ if(pairs[1][1] > pairs[0][1])
+ winner = 1;
+ else if(pairs[0][1] > pairs[1][1])
+ winner = -1;
+ else if(pairs[1][0] > pairs[0][0])
+ winner = 1;
+ else if(pairs[0][0] > pairs[1][0])
+ winner = -1;
+ break;
+ case onePair:
+ if(pairs[1][0] > pairs[0][0])
+ winner = 1;
+ else if(pairs[0][0] > pairs[1][0])
+ winner = -1;
+ break;
+ }
+
+ /*** NO WINNER FROM TYPES, TRY TO SPLIT WITH THE rest ***/
+ if(!winner)
+ {
+ for(c = numRest[0] - 1; c>=0; c--)
+ {
+ if(rest[1][c] / 4> rest[0][c] / 4)
+ {
+ winner = 1;
+ break;
+ }
+ else if(rest[0][c] / 4 > rest[1][c] / 4)
+ {
+ winner = -1;
+ break;
+ }
+ }
+ }
+ }
+ return winner;
+}
+
+void POKER_BestHand(int * cards1, int * cards2, int n1, int n2, int r1, int r2, int output[5])
+{
+ static int pos = 0;
+ static int start1 = 0;
+ static int start2 = 0;
+ static int currentHand[5];
+
+ if(pos == 5)
+ {
+ int temp[5];
+ CopyBytesBy4(temp, currentHand, 5);
+ qsort(temp, 5, sizeof(int), Compare);
+ if(POKER_Compare(output, temp) == 1)
+ CopyBytesBy4(output, temp, 5);
+ }
+ else
+ {
+ int oldStart, c;
+
+ if(pos >= r1)
+ {
+ oldStart = start2;
+ for(c = start2; c < n2 - (5 - pos - 1); c++)
+ {
+ start2 = c + 1;
+ currentHand[pos++] = cards2[c];
+ POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
+ pos--;
+ }
+ start2 = oldStart;
+ }
+ else
+ {
+ oldStart = start1;
+ for(c = start1; c < n1 - (r1 - pos - 1); c++)
+ {
+ start1 = c + 1;
+ currentHand[pos++] = cards1[c];
+ POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
+ pos--;
+ }
+ start1 = oldStart;
+ }
+
+ // Added this recently : was only using 5-r1 from cards2
+ if(pos >= r2)
+ {
+ oldStart = start1;
+ for(c = start1; c < n1 - (5 - pos - 1); c++)
+ {
+ start1 = c + 1;
+ currentHand[pos++] = cards1[c];
+ POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
+ pos--;
+ }
+ start1 = oldStart;
+ }
+ else
+ {
+ oldStart = start2;
+ for(c = start2; c < n2 - (r2 - pos - 1); c++)
+ {
+ start2 = c + 1;
+ currentHand[pos++] = cards2[c];
+ POKER_BestHand(cards1, cards2, n1, n2, r1, r2, output);
+ pos--;
+ }
+ start2 = oldStart;
+ }
+ }
+}
+
+/*
+void POKER_BestHand(int * cards, int n, int output[5])
+{
+ static int pos = 0;
+ static int start = 0;
+ static int currentHand[5];
+ int c;
+
+ for(c = start; c < n - (5 - pos - 1); c++)
+ {
+ currentHand[pos] = cards[c];
+ if(pos == 5 - 1)
+ {
+ int temp[5];
+ CopyBytesBy4(temp, currentHand, 5);
+ qsort(temp, 5, sizeof(int), Compare);
+ if(POKER_Compare(output, temp) == 1)
+ CopyBytesBy4(output, temp, 5);
+ }
+ else
+ {
+ int oldStart = start;
+ start = c + 1;
+ pos++;
+ POKER_BestHand(cards, n, output);
+ pos--;
+ start = oldStart;
+ }
+ }
+}
+*/
--- /dev/null
+/****************************************************************************
+ POKER Game Interface
+
+ Copyright (c) 2001 Jerome Jacovella-St-Louis
+ All Rights Reserved.
+
+ widow.ec - Widow Window
+****************************************************************************/
+import "poker.ec"
+
+class Widow : Window
+{
+ void OnRedraw(Surface surface)
+ {
+ Poker poker = (Poker) master;
+ int c;
+ for(c=0; c<widowNum; c++)
+ poker.DrawCard(surface, c * 15, 0, POKER_Card(widow[c]));
+ surface.SetForeground(red);
+ surface.WriteTextf(10, 130, "POT MONEY: %.2f", potMoney / 2.0);
+ }
+}
--- /dev/null
+/****************************************************************************
+ Tetris Game
+
+ Copyright (c) 2001-2007 Jerome Jacovella-St-Louis
+ All Rights Reserved.
+
+ tetris.ec - Tetris
+****************************************************************************/
+import "ecere"
+
+// --- Definitions ---
+
+define SERVER = 0;
+define CLIENT = 1;
+
+define NUM_COLUMNS = 8;
+define NUM_ROWS = 8;
+
+define CUBE_WIDTH = 40;
+define CUBE_HEIGHT = 40;
+
+define TETRIS_PORT = 7779;
+
+struct Piece
+{
+ int w, h;
+ int x0, x1;
+ byte data[9];
+};
+
+static Piece pieces[7] =
+{
+ {
+ 4, 1, -1, 1,
+ {
+ 1,1,1,1
+ }
+ },
+ {
+ 3, 2, 0, 0,
+ {
+ 4,4,4,
+ 4,0,0
+ }
+ },
+ {
+ 3, 2, 0, 0,
+ {
+ 3,3,3,
+ 0,0,3
+ }
+ },
+ {
+ 3, 2, 0, 0,
+ {
+ 5,5,0,
+ 0,5,5
+ }
+ },
+ {
+ 3, 2, 0, 0,
+ {
+ 0,1,1,
+ 1,1,0
+ }
+ },
+ {
+ 2, 2, 0, 0,
+ {
+ 2,2,
+ 2,2
+ }
+ },
+ {
+ 3, 2, 0, 0,
+ {
+ 2,2,2,
+ 0,2,0
+ }
+ }
+};
+
+define MSG_NEWGAME = 1;
+define MSG_POSITION = 2;
+
+typedef struct
+{
+ byte type;
+ byte player,x,y;
+} TPacket;
+
+define WIDTH = 12;
+define HEIGHT = 22;
+
+// --- Main Function ---
+class TetrisApp : GuiApplication
+{
+ appName = "ECERE Tetris";
+}
+
+Tetris tetris { };
+
+TetrisService service { };
+
+class TetrisService : Service
+{
+ port = TETRIS_PORT;
+ Tetris tetris;
+ void OnAccept()
+ {
+ if(!tetris.sockets[CLIENT] && !tetris.gameRunning)
+ {
+ TetrisSocket socket { this };
+ TPacket packet;
+
+ tetris.sockets[CLIENT] = socket;
+ packet.type = MSG_NEWGAME;
+ tetris.sockets[CLIENT].Send((byte *)&packet, sizeof(TPacket));
+ tetris.NewGame();
+ tetris.gameRunning = true;
+ tetris.EnableButtons();
+ tetris.Update(null);
+ }
+ }
+}
+
+class TetrisSocket : Socket
+{
+ // --- Tetris Communication ---
+ Tetris tetris;
+ static void OnDisconnect(int code)
+ {
+ if(this == tetris.sockets[CLIENT])
+ {
+ tetris.sockets[CLIENT] = null;
+ tetris.gameRunning = false;
+ }
+ else if(this == tetris.sockets[SERVER])
+ {
+ tetris.sockets[SERVER] = null;
+ tetris.gameRunning = false;
+ }
+
+ tetris.EnableButtons();
+ tetris.Update(null);
+ }
+
+ uint OnReceive(const byte * buffer, uint count)
+ {
+ if(count >= sizeof(TPacket))
+ {
+ TPacket packet = *(TPacket *)buffer;
+ switch(packet.type)
+ {
+ case MSG_POSITION:
+ break;
+ case MSG_NEWGAME:
+ tetris.gameRunning = true;
+ tetris.NewGame();
+ break;
+ }
+ return sizeof(TPacket);
+ }
+ return 0;
+ }
+
+ void OnConnect()
+ {
+ tetris.sockets[SERVER] = this;
+ tetris.gameRunning = true;
+ tetris.EnableButtons();
+ tetris.NewGame();
+ }
+}
+
+class Tetris : Window
+{
+ text = "ECERE Tetris";
+ hasClose = true;
+ clientSize = { 300, 420 };
+
+ Button host
+ {
+ this, text = "Host", position = { 10, 360 }, size = { 60, 20 };
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ if(service.Start())
+ {
+ hosting = true;
+ EnableButtons();
+ Update(null);
+ }
+ return true;
+ }
+
+ };
+ Button stop
+ {
+ this, text = "Stop", position = { 80, 360 }, size = { 60, 20 };
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ hosting = false;
+ service.Stop();
+ EnableButtons();
+ Update(null);
+ return true;
+ }
+ };
+ Button join
+ {
+ this, text = "Join", position = { 10, 380 }, size = { 40, 20 };
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ TetrisSocket socket { tetris = this };
+ sockets[SERVER] = socket;
+ socket.Connect(address.contents, TETRIS_PORT);
+ EnableButtons();
+ Update(null);
+ return true;
+ }
+ };
+ Button disconnect
+ {
+ this, text = "Disconnect", position = { 170, 370 }, size = { 100, 20 };
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ sockets[SERVER].Disconnect(0);
+ Update(null);
+ return true;
+ }
+ };
+ EditBox address
+ {
+ this, disabled = true, position = { 60, 380 }, size = { 100, 20 }, contents = "localhost";
+ };
+
+ bool hosting, gameRunning, local;
+ byte turn;
+ Bitmap squares[5];
+ Bitmap backgroundBmp { };
+ Socket sockets[2];
+ byte board[HEIGHT][WIDTH];
+ bool gameOver;
+ int angle;
+ int playerx, playery;
+ int newpiece;
+ int nextAngle, nextPiece;
+
+ background = black;
+ tabCycle = true;
+
+ // --- Tetris Utilities ---
+
+ void NewGame()
+ {
+ int x,y;
+ gameOver = false ;
+ for(y = 0; y<HEIGHT; y++)
+ for(x = 0; x<WIDTH; x++)
+ board[y][x] = 0;
+ turn = CLIENT;
+ Update(null);
+ RandomSeed((uint)(GetTime() * 1000));
+ nextPiece = GetRandom(0, 6);
+ nextAngle = GetRandom(0, 3);
+ NewPiece();
+ }
+
+ void EnableButtons()
+ {
+ join.disabled = false;
+ host.disabled = false;
+ disconnect.disabled = false;
+ stop.disabled = false;
+
+ if(!hosting)
+ stop.disabled = true;
+ if(!sockets[SERVER])
+ disconnect.disabled = true;
+
+ if(hosting || sockets[SERVER])
+ host.disabled = true;
+
+ if(sockets[CLIENT] || hosting)
+ join.disabled = true;
+
+ // address.disabled = join.disabled;
+ }
+
+ // --- Tetris Window Class ---
+
+ void OnRedraw(Surface surface)
+ {
+ // Background...
+ surface.Blit(backgroundBmp, 0,0, 0,0, backgroundBmp.width, backgroundBmp.height);
+
+ //if(GameRunning)
+ {
+ Piece * piece = &pieces[newpiece];
+ int x,y;
+ for(x = 0; x<WIDTH; x++)
+ {
+ for(y = 0; y<HEIGHT; y++)
+ {
+ int square = board[y][x];
+ if(square)
+ surface.Blit(squares[square-1], x * 16, y * 16, 0, 0, 16, 16);
+ }
+ }
+ if(!gameOver)
+ {
+ for(x = 0; x<piece->w; x++)
+ for(y = 0; y<piece->h; y++)
+ {
+ int square;
+ int rx, ry;
+
+ switch(angle)
+ {
+ case 0: rx = x; ry = y; break;
+ case 1: rx = piece->h-1 - y; ry = x; break;
+ case 2: rx = piece->w-1 - x; ry = piece->h -1- y; break;
+ case 3: rx = y; ry = piece->w-1 - x; break;
+ }
+
+ switch(angle)
+ {
+ case 0: case 2: rx += piece->x0; break;
+ case 1: case 3: rx += piece->x1; break;
+ }
+
+ square = piece->data[y * piece->w + x];
+ if(square)
+ surface.Blit(squares[square-1], (rx + playerx) * 16, (ry + playery) * 16, 0, 0, 16, 16);
+ }
+ }
+ piece = &pieces[nextPiece];
+ for(x = 0; x<piece->w; x++)
+ for(y = 0; y<piece->h; y++)
+ {
+ int square;
+ int rx, ry;
+
+ switch(nextAngle)
+ {
+ case 0: rx = x; ry = y; break;
+ case 1: rx = piece->h-1 - y; ry = x; break;
+ case 2: rx = piece->w-1 - x; ry = piece->h -1- y; break;
+ case 3: rx = y; ry = piece->w-1 - x; break;
+ }
+
+ switch(nextAngle)
+ {
+ case 0: case 2: rx += piece->x0; break;
+ case 1: case 3: rx += piece->x1; break;
+ }
+
+ square = piece->data[y * piece->w + x];
+ if(square)
+ surface.Blit(squares[square-1], rx * 16 + (WIDTH + 2) * 16, ry * 16 + 10, 0, 0, 16, 16);
+ }
+ }
+ }
+
+ bool OnCreate()
+ {
+ playerx = 5;
+ NewGame();
+ EnableButtons();
+ return true;
+ }
+
+ void OnDestroy()
+ {
+ if(sockets[0]) sockets[0].OnDisconnect = null;
+ if(sockets[1]) sockets[1].OnDisconnect = null;
+ }
+
+ bool OnLoadGraphics()
+ {
+ int c;
+ Bitmap tetrisBlocks { };
+ if(tetrisBlocks.Load(":tetris.bmp", null, null))
+ {
+ for(c=0; c<5; c++)
+ {
+ if(!squares[c]) squares[c] = Bitmap { };
+ squares[c].Allocate(null, 16,16,16, pixelFormat888, false);
+ squares[c].Grab(tetrisBlocks, c*16, 0);
+ squares[c].MakeDD(displaySystem);
+ }
+
+ backgroundBmp.Allocate(null, 192,352,192, pixelFormat888, false);
+ backgroundBmp.Grab(tetrisBlocks, 0, 24);
+ backgroundBmp.MakeDD(displaySystem);
+ }
+ delete tetrisBlocks;
+ return true;
+ }
+
+ void OnUnloadGraphics()
+ {
+ int c;
+ for(c=0; c<5; c++)
+ squares[c].Free();
+ backgroundBmp.Free();
+ }
+
+ bool OnKeyDown(Key key, unichar ch)
+ {
+ switch(key)
+ {
+ case escape:
+ Destroy(0);
+ break;
+ }
+ return true;
+ }
+
+ void NewPiece()
+ {
+ newpiece = nextPiece;
+ angle = nextAngle;
+ playerx = 5;
+ playery = 0;
+ if(CheckPiece())
+ {
+ gameOver = true;
+ }
+ else
+ {
+ nextPiece = GetRandom(0, 6);
+ nextAngle = GetRandom(0, 3);
+ }
+ }
+
+ void FreezePiece()
+ {
+ Piece * piece = &pieces[newpiece];
+ int x,y;
+ int numLines = 0;
+ for(x = 0; x<piece->w; x++)
+ {
+ for(y = 0; y<piece->h; y++)
+ {
+ int square;
+ int rx, ry;
+
+ switch(angle)
+ {
+ case 0: rx = x; ry = y; break;
+ case 1: rx = piece->h-1 - y; ry = x; break;
+ case 2: rx = piece->w-1 - x; ry = piece->h -1- y; break;
+ case 3: rx = y; ry = piece->w-1 - x; break;
+ }
+
+ switch(angle)
+ {
+ case 0: case 2: rx += piece->x0; break;
+ case 1: case 3: rx += piece->x1; break;
+ }
+ square = piece->data[y * piece->w + x];
+ if(square)
+ board[ry + playery][rx + playerx] = (byte)square;
+ }
+ }
+ for(y = HEIGHT - 1; y >= 0; y--)
+ {
+ for(x = 0; x < WIDTH; x++)
+ {
+ if(!board[y][x]) break;
+ }
+ if(x == WIDTH)
+ {
+ numLines++;
+ if(y > 0)
+ memmove(&board[1], &board, y * WIDTH);
+ memset(&board, 0, WIDTH);
+ y++;
+ }
+ }
+
+ NewPiece();
+ }
+
+ void DropPiece()
+ {
+ while(!CheckPiece())
+ {
+ playery++;
+ }
+ playery--;
+ FreezePiece();
+ }
+
+ bool CheckPiece()
+ {
+ Piece * piece = &pieces[newpiece];
+ bool result = false;
+ if(((angle == 0 || angle == 2) ? piece->h : piece->w) + playery > HEIGHT)
+ {
+ //playery = HEIGHT - ((angle == 0 || angle == 2) ? piece->h : piece->w);
+ result = true;
+ }
+ if(!result)
+ {
+ int x,y;
+ for(x = 0; x<piece->w && !result; x++)
+ for(y = 0; y<piece->h && !result; y++)
+ {
+ int square;
+ int rx, ry;
+
+ switch(angle)
+ {
+ case 0: rx = x; ry = y; break;
+ case 1: rx = piece->h-1 - y; ry = x; break;
+ case 2: rx = piece->w-1 - x; ry = piece->h -1- y; break;
+ case 3: rx = y; ry = piece->w-1 - x; break;
+ }
+
+ switch(angle)
+ {
+ case 0: case 2: rx += piece->x0; break;
+ case 1: case 3: rx += piece->x1; break;
+ }
+ square = piece->data[y * piece->w + x];
+ if(square && board[ry + playery][rx + playerx])
+ {
+ //playery--;
+ result = true;
+ }
+ }
+ }
+ /*if(result)
+ FreezePiece();*/
+ return result;
+ }
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ Piece * piece = &pieces[newpiece];
+ if(!gameOver)
+ {
+ switch(key)
+ {
+ case left:
+ case right:
+ if(key == left) playerx--; else playerx++;
+ playerx = Max(playerx, -((angle == 0 || angle == 2) ? (piece->x0) : (piece->x1)));
+ playerx = Min(playerx, 12 - ((angle == 0 || angle == 2) ? (piece->x0 + piece->w) : (piece->x1 + piece->h)));
+ if(CheckPiece())
+ {
+ if(key == left) playerx++; else playerx--;
+ }
+ break;
+ case down:
+ playery++;
+ if(CheckPiece())
+ {
+ playery--;
+ FreezePiece();
+ }
+ break;
+ case up:
+ {
+ int oldx = playerx;
+ angle++;
+ if(angle>3) angle = 0;
+ playerx = Max(playerx, -((angle == 0 || angle == 2) ? (piece->x0) : (piece->x1)));
+ playerx = Min(playerx, 12 - ((angle == 0 || angle == 2) ? (piece->x0 + piece->w) : (piece->x1 + piece->h)));
+
+ if(CheckPiece())
+ {
+ angle--;
+ if(angle < 0) angle += 4;
+ playerx = oldx;
+ }
+ break;
+ }
+ case space:
+ {
+ DropPiece();
+ break;
+ }
+ }
+ Update(null);
+ }
+ return true;
+ }
+
+ bool OnLeftButtonDown(int x, int y, Modifiers mods)
+ {
+ x /= CUBE_WIDTH;
+ y /= CUBE_HEIGHT;
+
+ if(sockets[1-turn])
+ {
+ if(x < NUM_COLUMNS && y < NUM_ROWS)
+ {
+ TPacket packet;
+ packet.type = MSG_POSITION;
+ packet.player = turn;
+ packet.x = (byte)x;
+ packet.y = (byte)y;
+ sockets[turn].Send((byte *)&packet, sizeof(TPacket));
+ }
+ }
+ return true;
+ }
+}
--- /dev/null
+
+ECERE Project File
+
+Version 0.1a
+
+Target "tetris"
+
+ Configurations
+
+ + Debug
+
+ Compiler Options
+
+ Intermediate Directory = debug
+ Debug = True
+ Optimize = None
+ Profile = False
+ MemoryGuard = False
+ AllWarnings = True
+ Strict Name Spaces = False
+
+ Linker Options
+
+ Target Name = tetris
+ Target Type = Executable
+ Target Directory = debug
+ Console = False
+
+ Libraries = ecere
+
+ + Release
+
+ Compiler Options
+
+ Intermediate Directory = release
+ Debug = False
+ Optimize = Speed
+ Profile = False
+ MemoryGuard = False
+ AllWarnings = True
+ Strict Name Spaces = False
+
+ Linker Options
+
+ Target Name = tetris
+ Target Type = Executable
+ Target Directory = release
+ Console = False
+
+ Libraries = ecere
+
+ + memguard
+
+ Compiler Options
+
+ Intermediate Directory = memguard
+ Debug = True
+ Optimize = None
+ Profile = False
+ MemoryGuard = True
+ AllWarnings = True
+ Strict Name Spaces = False
+
+ Linker Options
+
+ Target Name = tetris
+ Target Type = Executable
+ Target Directory = memguard
+ Console = False
+
+ Libraries = memguard
+
+ Files
+
+ - tetris.ec
+
+ Resources
+
+ = data/tetris.bmp
--- /dev/null
+
+ECERE Project File
+
+Version 0a
+
+Target "tongIts"
+
+ Compiler Options
+
+ Intermediate Directory = obj
+ Debug = True
+ Optimize = False
+ Profile = False
+ AllWarnings = False
+
+ Linker Options
+
+ Target Name = tongIts
+ Target Type = Executable
+ Console = False
+
+ Libraries = ecere
+
+ Files
+
+ - tongits.ec
+
+ Resources
+
+ = data/ecereCard.bmp
+ = data/cards.pcx
--- /dev/null
+import "ecere"
+
+#define MCARD(k,n) ((n) * 4 + (k))
+#define NUMBER(id) ((id) / 4)
+#define KIND(id) ((id) % 4)
+#define OFFSETTER1 15
+#define OFFSETTER2 120
+#define HOUSETYPE_STRAIGHT 0
+#define HOUSETYPE_KIND 1
+
+typedef struct
+{
+ int typeOfHouse;
+
+ union
+ {
+ struct straight
+ {
+ int first, last;
+ int suit;
+ } straight;
+ struct kind
+ {
+ int number;
+ bool suits[4];
+ } kind;
+ };
+} House;
+
+typedef struct
+{
+ int numCards;
+ int cardValues[13];
+ House houseDown[4];
+ int numHouseDown;
+ bool cardLifted[13];
+ bool callTag;
+} Player;
+
+int cards[52];
+int discard[28];
+int discardCounter = 0;
+int deckCounter = 0;
+int numOfPlayers = 4;
+int currentPlayer = 0;
+int cardToReposition = 0;
+int xMouseMove=0,yMouseMove=0,xLeftButtonUp=0,yLeftButtonUp=0;
+int xCursorPositionAtCard=0,yCursorPositionAtCard=0,width=0,height=0;
+int dragCard = -1;
+Player player[4];
+Point xyPositions[4] =
+{
+ {30,150},
+ {30,500},
+ {600,500},
+ {600,150}
+};
+
+bool flagButtonDown, leftDoubleClick, gameOver;
+
+//player[0].houseDown[0].straight.suit
+
+void NewDeckOfCards()
+{
+ int i;
+ for(i=0;i<52;i++)
+ {
+ cards[i]=i;
+ }
+}
+
+void Shuffle()
+{
+ int i,j,randNum;
+ for(i=0;i<52;i++)
+ {
+ randNum = GetRandom(0,51);
+ j=cards[i];
+ cards[i]=cards[randNum];
+ cards[randNum]=j;
+ }
+}
+
+void DealCards(int numPlayers)
+{
+ int c, p;
+
+ player[0].cardValues[player[0].numCards++] = cards[deckCounter++];
+ for(c = 0; c<((numPlayers > 3) ? 9 : 12); c++)
+ for(p = 0; p<numPlayers; p++)
+ player[(p+1)%numPlayers].cardValues[player[(p+1)%numPlayers].numCards++] = cards[deckCounter++];
+ //player[0].houseDown[0].straight.suit
+}
+
+int CheckHouse(int cardsToCheck,int * checkIfHouse)
+{
+ int i,straight=0,house=0;
+ for(i=cardsToCheck-1;i>=0;i--)
+ {
+ if(checkIfHouse[i] == checkIfHouse[i-1] + 4)
+ {
+ straight++; //possible straight house
+ }
+ else if(NUMBER(checkIfHouse[i]) == NUMBER(checkIfHouse[i-1]))
+ {
+ house++; //possible 3or4 of a kind house
+ }
+ }
+ if(straight == cardsToCheck-1)
+ return 0;
+ else if(house == cardsToCheck-1)
+ return 1;
+ else
+ return -1;
+}
+
+int CompareInteger(int * a, int * b)
+{
+ if(*a > *b)
+ return 1;
+ else if(*b > *a)
+ return -1;
+ else return 0;
+}
+
+void SortPlayerCards()
+{
+ int c;
+ for(c=0;c<numOfPlayers;c++)
+ {
+ qsort(player[c].cardValues,player[c].numCards,sizeof(int),CompareInteger);
+ //qsort(tempHouse,tempCtr,sizeof(int),CompareInteger);
+ }
+}
+
+class TongIts : Window
+{
+ Bitmap bitmapCards[52];
+ Bitmap cardBack {};
+ Button drawButton[4], chowButton[4], dumpButton[4], callButton[4], showButton[4], doneButton[4];
+
+ hasClose = true;
+ hasMinimize = true;
+ hasMaximize = true;
+ background = Color { 113,156,169 };
+ borderStyle = sizable;
+ text = "Tong-Its";
+ size = Size { 900,700 };
+
+ bool OnCreate()
+ {
+ int c;
+ RandomSeed((int)(GetTime() * 1000));
+ NewDeckOfCards();
+ Shuffle();
+ DealCards(numOfPlayers);
+ SortPlayerCards();
+ for(c = 0; c<numOfPlayers; c++)
+ {
+ drawButton[c] = Button { this, text = "Draw Card", position = xyPositions[c], size = Size { 80,20 }, id = c*6, disabled = true, NotifyClicked = DrawClicked };
+ chowButton[c] = Button { this, text = "Chow", position = Point { xyPositions[c].x + 80,xyPositions[c].y }, size = Size { 80,20 }, id = c*6, disabled = true, NotifyClicked = ChowClicked };
+ dumpButton[c] = Button { this, text = "Dump", position = Point { xyPositions[c].x + 160, xyPositions[c].y }, size = Size { 80,20 }, id = c*6, disabled = true, NotifyClicked = DumpClicked };
+ callButton[c] = Button { this, text = "Call", position = Point { xyPositions[c].x, xyPositions[c].y + 20 }, size = Size { 80,20 }, id = c*6, disabled = true, NotifyClicked = CallClicked };
+ showButton[c] = Button { this, text = "Show", position = Point { xyPositions[c].x + 80, xyPositions[c].y + 20 }, size = Size { 80,20 }, id = c*6, disabled = true, NotifyClicked = ShowClicked };
+ doneButton[c] = Button { this, text = "Done", position = Point { xyPositions[c].x + 160, xyPositions[c].y + 20 },size = Size { 80,20 }, id = c*6, disabled = true, NotifyClicked = DoneClicked };
+ }
+ showButton[currentPlayer].disabled = false;
+ dumpButton[currentPlayer].disabled = false;
+ return true;
+ }
+
+ bool OnLoadGraphics()
+ {
+ int i;
+ Bitmap ptrCardLoad {};
+ ptrCardLoad.Load(":cards.pcx",null,null);
+ cardBack.LoadT(":ecereCard.bmp", null, displaySystem);
+
+ for(i=0;i<52;i++)
+ {
+ Bitmap bitmap { transparent = true };
+ bitmap.Allocate(null,ptrCardLoad.width, ptrCardLoad.height/52,0,pixelFormat8,true);
+ CopyBytesBy4(bitmap.palette, ptrCardLoad.palette, 256);
+ bitmap.Grab(ptrCardLoad,0,(ptrCardLoad.height/52)*i);
+ bitmap.MakeDD(displaySystem);
+ bitmapCards[i] = bitmap;
+ }
+ delete ptrCardLoad;
+ return true;
+ }
+
+ void OnUnloadGraphics()
+ {
+ int i;
+ for(i=0;i<52;i++)
+ bitmapCards[i].Free();
+ }
+
+ void GameOver()
+ {
+ /*
+ Window gameOverBox
+ {
+ this, hasClose = true, background = LightBlue, text = "Game Over", [position.y] = A_CENTER|20, size = Size { 300, 200 }
+ };
+ Button { gameOverBox, text = "Close", [position.y] = A_CENTER|80, size = Size { 80,20 } };
+ */
+ gameOver = true;
+ }
+
+ void OnRedraw(Surface surface)
+ {
+ int h=0,i=0,j=0,k=0,x=0;
+
+ surface.Rectangle(375, 315, 495, 475);
+
+ if(gameOver)
+ {
+ surface.SetForeground(blue);
+ surface.SetBackground(red);
+ // surface.Area(375,100,495,150);
+ surface.Area(375,370,495,420);
+ //surface.TextOpacity(true);
+ // surface.WriteTextf(398, 115,"GAME OVER");
+ surface.WriteTextf(398, 385,"GAME OVER");
+ }
+
+ for(i=deckCounter,x=0;i<52;i+=5,x+=2)
+ {
+ Bitmap bitmap = cardBack;
+ surface.Blit(bitmap,400 + x, 195 + x,0,0, bitmap.width,bitmap.height);
+ }
+
+ if(discardCounter > 0)
+ {
+ Bitmap bitmap = bitmapCards[discard[discardCounter-1]];
+ surface.Blit(bitmap, xLeftButtonUp, yLeftButtonUp,0,0, bitmap.width,bitmap.height);
+ }
+
+ for(j=0;j<numOfPlayers;j++)
+ {
+ for(i=0;i<player[j].numCards;i++)
+ {
+ if(player[j].cardValues[i] != dragCard || (!flagButtonDown))
+ {
+ Bitmap bitmap = bitmapCards[player[j].cardValues[i]];
+ if(player[j].cardLifted[i])
+ {
+ surface.Blit(bitmap,xyPositions[j].x + OFFSETTER1 * i,xyPositions[j].y - OFFSETTER2 - 20,0,0, bitmap.width,bitmap.height);
+ }
+ else
+ {
+ surface.Blit(bitmap,xyPositions[j].x + OFFSETTER1 * i,xyPositions[j].y - OFFSETTER2,0,0, bitmap.width,bitmap.height);
+ }
+ }
+ }
+ for(i=0,h=0;i<player[j].numHouseDown;i++,h++)
+ {
+ if(player[j].houseDown[i].typeOfHouse == 0)
+ {
+ for(k=player[j].houseDown[i].straight.first;k<=player[j].houseDown[i].straight.last;k++)
+ {
+ Bitmap bitmap = bitmapCards[MCARD((player[j].houseDown[i].straight.suit),(k))];
+ surface.Blit(bitmap,xyPositions[j].x + OFFSETTER1 * h,xyPositions[j].y + 75,0,0, bitmap.width,bitmap.height);
+ h++;
+ }
+ }
+
+ if(player[j].houseDown[i].typeOfHouse == 1)
+ {
+ for(k=0;k<4;k++) //player[j].houseDown[i].kind.suits[k]
+ {
+ if(player[j].houseDown[i].kind.suits[k] == true)
+ {
+ Bitmap bitmap = bitmapCards[MCARD((k),(player[j].houseDown[i].kind.number))];
+ surface.Blit(bitmap,xyPositions[j].x + OFFSETTER1 * h,xyPositions[j].y + 75,0,0, bitmap.width,bitmap.height);
+ h++;
+ } //_2D xyPositions[4] = {{30,150},{30,500},{540,500},{540,150}};
+ }
+ }
+ }
+ }
+ if(flagButtonDown)
+ {
+ for(i=0;i<player[currentPlayer].numCards;i++)
+ {
+ Bitmap bitmap = bitmapCards[player[currentPlayer].cardValues[i]];
+ if(player[currentPlayer].cardValues[i] == dragCard)
+ {
+ surface.Blit(bitmap,xMouseMove + xCursorPositionAtCard,yMouseMove + yCursorPositionAtCard,0,0, bitmap.width,bitmap.height);
+ }
+ }
+ }
+ if(gameOver)
+ {
+ surface.SetForeground(blue);
+ surface.SetBackground(red);
+ // surface.Area(375,100,495,150);
+ surface.Area(375,370,495,420);
+ //surface.TextOpacity(true);
+ // surface.WriteTextf(398, 115,"GAME OVER");
+ surface.WriteTextf(398, 385,"GAME OVER");
+ for(i=0;i<numOfPlayers;i++)
+ {
+ drawButton[i].disabled = true;
+ chowButton[i].disabled = true;
+ dumpButton[i].disabled = true;
+ callButton[i].disabled = true;
+ showButton[i].disabled = true;
+ doneButton[i].disabled = true;
+ }
+ // eWindow_Create("MessageBox",MSGBOX_OK,ES_CAPTION,window,null,A_LEFT,A_RIGHT,200,100,0,null,0,null,0);
+ }
+ /* if(j == 1)
+ {
+ for(i=0;i<player[j].numCards;i++)
+ {
+ Bitmap bitmap = bitmapCards[MCARD(KIND(player[2].cardValues[i]),NUMBER(player[2].cardValues[i]))];
+ surface.Blit(bitmap,30+15*i,500,0,0, bitmap.width,bitmap.height);
+ }
+ }
+ else
+ {
+ for(i=0;i<player[j].numCards;i++)
+ {
+ //Bitmap bitmap1 = bitmapCards[MCARD(KIND(player[1].cardValues[i]),NUMBER(player[1].cardValues[i]))];
+ Bitmap bitmap = cardBack;
+ surface.Blit(bitmap,30+15*i,30+nextLane,0,0, bitmap.width,bitmap.height);
+ }
+ }
+ }*/
+ }
+
+ bool DrawClicked(Button button, int x, int y, Modifiers mods)
+ {
+ player[currentPlayer].cardValues[player[currentPlayer].numCards++] = cards[deckCounter++];
+ drawButton[currentPlayer].disabled = true;
+ chowButton[currentPlayer].disabled = true;
+ callButton[currentPlayer].disabled = true;
+ showButton[currentPlayer].disabled = false;
+ dumpButton[currentPlayer].disabled = false;
+ Update(null);
+ return true;
+ }
+
+ bool ChowClicked(Button button, int x, int y, Modifiers mods)
+ {
+ int i, j, suit, number;
+ int tempCtr = 0;
+ int tempHouse[13];
+ for(i=0;i<13;i++)
+ {
+ tempHouse[i]=0;
+ }
+ suit = KIND(discard[discardCounter-1]);
+ number = NUMBER(discard[discardCounter-1]);
+ tempHouse[tempCtr++] = discard[discardCounter-1];
+ for(i=0;i<player[currentPlayer].numCards;i++)
+ {
+ if(player[currentPlayer].cardLifted[i])
+ {
+ tempHouse[tempCtr++] = player[currentPlayer].cardValues[i];
+ }
+ }
+ if(tempCtr >= 3)
+ {
+ int checkResult;
+
+ qsort(tempHouse,tempCtr,sizeof(int),CompareInteger);
+ checkResult = CheckHouse(tempCtr,tempHouse);
+ switch(checkResult)
+ {
+ // 3/4 of a kind
+ case 1:
+ {
+ House * house = &player[currentPlayer].houseDown[player[currentPlayer].numHouseDown];
+ house->typeOfHouse = checkResult;
+ for(i=0;i<tempCtr;i++)
+ {
+ house->kind.number = NUMBER(tempHouse[i]);
+ house->kind.suits[KIND(tempHouse[i])] = true;
+ }
+ player[currentPlayer].numHouseDown++;
+ break;
+ }
+ case 0:
+ {
+ House * house = &player[currentPlayer].houseDown[player[currentPlayer].numHouseDown];
+ house->typeOfHouse = checkResult;
+ house->straight.first = NUMBER(tempHouse[0]);
+ house->straight.last = NUMBER(tempHouse[tempCtr-1]);
+ house->straight.suit = KIND(tempHouse[0]);
+ player[currentPlayer].numHouseDown++;
+ break;
+ }
+ case -1:
+ {
+ return true;
+ break;
+ }
+ }
+ for(i=0,j=0;i<player[currentPlayer].numCards;i++)
+ {
+ if(!player[currentPlayer].cardLifted[i])
+ {
+ player[currentPlayer].cardValues[j] = player[currentPlayer].cardValues[i];
+ player[currentPlayer].cardLifted[j] = false;
+ j++;
+ }
+ }
+ player[currentPlayer].numCards = j;
+ discard[discardCounter--];
+ drawButton[currentPlayer].disabled = true;
+ chowButton[currentPlayer].disabled = true;
+ callButton[currentPlayer].disabled = true;
+ showButton[currentPlayer].disabled = false;
+ dumpButton[currentPlayer].disabled = false;
+ Update(null);
+ }
+ if(player[currentPlayer].numCards == 0)
+ {
+ GameOver();
+ }
+ return true;
+ }
+
+ bool DumpClicked(Button button, int x, int y, Modifiers mods)
+ {
+ MessageBox { text = button.text }.Create();
+ return true;
+ }
+
+ bool CallClicked(Button button, int x, int y, Modifiers mods)
+ {
+ MessageBox { text = button.text }.Create();
+ return true;
+ }
+
+ bool ShowClicked(Button button, int x, int y, Modifiers mods)
+ {
+ int i, j;
+ int tempHouse[13];
+ int tempCtr = 0;
+ for(i=0;i<13;i++)
+ {
+ tempHouse[i]=0;
+ }
+ for(i=0;i<player[currentPlayer].numCards;i++)
+ {
+ if(player[currentPlayer].cardLifted[i])
+ {
+ tempHouse[tempCtr++] = player[currentPlayer].cardValues[i];
+ }
+ }
+ if(tempCtr >= 3)
+ {
+ int checkResult;
+ qsort(tempHouse,tempCtr,sizeof(int),CompareInteger);
+ checkResult = CheckHouse(tempCtr,tempHouse);
+ switch(checkResult)
+ {
+ // 3/4 of a kind
+ case 1:
+ {
+ House * house = &player[currentPlayer].houseDown[player[currentPlayer].numHouseDown];
+ house->typeOfHouse = checkResult;
+ for(i=0;i<tempCtr;i++)
+ {
+ house->kind.number = NUMBER(tempHouse[i]);
+ house->kind.suits[KIND(tempHouse[i])] = true;
+ }
+ player[currentPlayer].numHouseDown++;
+ break;
+ }
+ case 0:
+ {
+ House * house = &player[currentPlayer].houseDown[player[currentPlayer].numHouseDown];
+ house->typeOfHouse = checkResult;
+ house->straight.first = NUMBER(tempHouse[0]);
+ house->straight.last = NUMBER(tempHouse[tempCtr-1]);
+ house->straight.suit = KIND(tempHouse[0]);
+ player[currentPlayer].numHouseDown++;
+ break;
+ }
+ case -1:
+ {
+ return true; //false;
+ break;
+ }
+ }
+ for(i=0,j=0;i<player[currentPlayer].numCards;i++)
+ {
+ if(!player[currentPlayer].cardLifted[i])
+ {
+ player[currentPlayer].cardValues[j] = player[currentPlayer].cardValues[i];
+ player[currentPlayer].cardLifted[j] = false;
+ j++;
+ }
+ }
+ player[currentPlayer].numCards = j;
+ if(player[currentPlayer].numCards == 0)
+ {
+ GameOver();
+ }
+ Update(null);
+ }
+ return true;
+ }
+
+ bool DoneClicked(Button button, int x, int y, Modifiers mods)
+ {
+ MessageBox { text = button.text }.Create();
+ return true;
+ }
+
+ bool OnMouseMove(int x, int y, Modifiers mods)
+ {
+ if(flagButtonDown)
+ {
+ xMouseMove = x;
+ yMouseMove = y;
+ Capture();
+ Update(null);
+ }
+ return true;
+ }
+
+ bool OnLeftButtonDown(int x, int y, Modifiers mods)
+ {
+ int i;
+ if(!gameOver)
+ {
+ for(i=player[currentPlayer].numCards-1;i>=0;i--)
+ {
+ Bitmap bitmap = bitmapCards[player[currentPlayer].cardValues[i]];
+ if(Box {
+ xyPositions[currentPlayer].x + (OFFSETTER1 * i),
+ (player[currentPlayer].cardLifted[i] ? (xyPositions[currentPlayer].y - OFFSETTER2 - 20) :( xyPositions[currentPlayer].y - OFFSETTER2)),
+ bitmap.width + (xyPositions[currentPlayer].x + OFFSETTER1 * i),
+ bitmap.height + (player[currentPlayer].cardLifted[i] ? (xyPositions[currentPlayer].y - OFFSETTER2 - 20) : (xyPositions[currentPlayer].y - OFFSETTER2))
+ }.IsPointInside(Point { x, y }) && drawButton[currentPlayer].disabled)
+ {
+ dragCard = player[currentPlayer].cardValues[i];
+ cardToReposition = i;
+ width = bitmap.width;
+ height = bitmap.height;
+ xCursorPositionAtCard = (xyPositions[currentPlayer].x + (OFFSETTER1 * i)) - x;
+ yCursorPositionAtCard = (player[currentPlayer].cardLifted[i] ?
+ (xyPositions[currentPlayer].y - OFFSETTER2 - y - 20) :
+ (xyPositions[currentPlayer].y - OFFSETTER2 - y));
+ flagButtonDown = true;
+ OnMouseMove(x,y,mods);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ bool OnLeftButtonUp(int x, int y, Modifiers mods)
+ {
+ int h,i,j;
+ Box boxDiscard={375, 315, 495, 475};
+ Box boxCard = {x + xCursorPositionAtCard,y + yCursorPositionAtCard, x + xCursorPositionAtCard + width - 1, y + yCursorPositionAtCard + height - 1};
+ if(flagButtonDown)
+ {
+ if(boxCard.Overlap(boxDiscard))
+ {
+ xLeftButtonUp = 400;
+ yLeftButtonUp = 350;
+ CopyBytesBy4(&player[currentPlayer].cardValues[cardToReposition],
+ &player[currentPlayer].cardValues[cardToReposition+1],
+ player[currentPlayer].numCards-1-cardToReposition);
+ player[currentPlayer].numCards--;
+ discard[discardCounter++] = dragCard;
+ if(player[currentPlayer].numCards == 0 || deckCounter == 52)
+ {
+ GameOver();
+ }
+ else
+ {
+ for(i=0;i<player[currentPlayer].numCards;i++)
+ {
+ player[currentPlayer].cardLifted[i] = false;
+ }
+ drawButton[currentPlayer].disabled = true;
+ chowButton[currentPlayer].disabled = true;
+ dumpButton[currentPlayer].disabled = true;
+ callButton[currentPlayer].disabled = true;
+ showButton[currentPlayer].disabled = true;
+ doneButton[currentPlayer].disabled = true;
+ player[currentPlayer].callTag = false;
+ currentPlayer++;
+ currentPlayer %= numOfPlayers;
+ drawButton[currentPlayer].disabled = false;
+ chowButton[currentPlayer].disabled = false;
+ if(player[currentPlayer].numHouseDown >= 2 && player[currentPlayer].callTag == false)
+ callButton[currentPlayer].disabled = false;
+ }
+ }
+ else
+ {
+ for(j=0;j<numOfPlayers;j++)
+ {
+ Bitmap bitmap = cardBack;
+ Box boxHouseDown =
+ {
+ xyPositions[j].x,xyPositions[j].y + 75,
+ 0, xyPositions[j].y + 75 + bitmap.height
+ };
+ for(i=0;i<player[j].numHouseDown;i++)
+ {
+ if(player[j].houseDown[i].typeOfHouse == 0)
+ {
+ boxHouseDown.right = boxHouseDown.left + bitmap.width +
+ (player[j].houseDown[i].straight.last - player[j].houseDown[i].straight.first) * OFFSETTER1 - 1;
+ if(boxCard.Overlap(boxHouseDown))
+ {
+ if(dragCard == MCARD((player[j].houseDown[i].straight.suit),(player[j].houseDown[i].straight.first)) - 4)
+ {
+ player[j].houseDown[i].straight.first --;
+ CopyBytesBy4(&player[currentPlayer].cardValues[cardToReposition],
+ &player[currentPlayer].cardValues[cardToReposition+1],
+ player[currentPlayer].numCards-1-cardToReposition);
+ player[currentPlayer].numCards--;
+ player[j].callTag = true;
+ j = numOfPlayers;
+ break;
+
+ }
+ else if(dragCard == MCARD((player[j].houseDown[i].straight.suit),(player[j].houseDown[i].straight.last )) + 4)
+ {
+ player[j].houseDown[i].straight.last ++;
+ CopyBytesBy4(&player[currentPlayer].cardValues[cardToReposition],
+ &player[currentPlayer].cardValues[cardToReposition+1],
+ player[currentPlayer].numCards-1-cardToReposition);
+ player[currentPlayer].numCards--;
+ player[j].callTag = true;
+ j = numOfPlayers;
+ break;
+ }
+ }
+ boxHouseDown.left +=
+ (player[j].houseDown[i].straight.last - player[j].houseDown[i].straight.first + 2) * OFFSETTER1;
+ }
+ else if(player[j].houseDown[i].typeOfHouse == 1)
+ {
+ if(player[j].houseDown[i].kind.suits[0] == false || player[j].houseDown[i].kind.suits[1] == false ||
+ player[j].houseDown[i].kind.suits[2] == false || player[j].houseDown[i].kind.suits[3] == false)
+ {
+ h=4;
+ boxHouseDown.right = boxHouseDown.left + (2 * OFFSETTER1) + bitmap.width - 1;
+ }
+ else
+ {
+ h=5;
+ }
+ if(boxCard.Overlap(boxHouseDown))
+ {
+ if(NUMBER(dragCard) == player[j].houseDown[i].kind.number)
+ {
+ player[j].houseDown[i].kind.suits[KIND(dragCard)] = true;
+ CopyBytesBy4(&player[currentPlayer].cardValues[cardToReposition],
+ &player[currentPlayer].cardValues[cardToReposition+1],
+ player[currentPlayer].numCards-1-cardToReposition);
+ player[currentPlayer].numCards--;
+ player[j].callTag = true;
+ j = numOfPlayers;
+ break;
+ }
+ }
+ boxHouseDown.left += (h * OFFSETTER1);
+ }
+ }
+ }
+ }
+ flagButtonDown = false;
+ ReleaseCapture();
+ Update(null);
+ }
+ return true;
+ }
+
+ bool OnLeftDoubleClick(int x, int y, Modifiers mods)
+ {
+ int i;
+ for(i=player[currentPlayer].numCards-1;i>=0;i--)
+ {
+ Bitmap bitmap = bitmapCards[player[currentPlayer].cardValues[i]];
+
+ if(Box {
+ xyPositions[currentPlayer].x + (OFFSETTER1 * i),
+ (player[currentPlayer].cardLifted[i] ? (xyPositions[currentPlayer].y - OFFSETTER2 - 20) :(xyPositions[currentPlayer].y - OFFSETTER2)),
+ bitmap.width + (xyPositions[currentPlayer].x + OFFSETTER1 * i),
+ bitmap.height + (player[currentPlayer].cardLifted[i] ? (xyPositions[currentPlayer].y - OFFSETTER2 - 20) : (xyPositions[currentPlayer].y - OFFSETTER2))
+ }.IsPointInside(Point{x,y}))
+ {
+ player[currentPlayer].cardLifted[i] ^= true;
+ Update(null);
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+ bool OnRightButtonDown(int x, int y, Modifiers mods)
+ {
+ int i;
+
+ if(!gameOver)
+ {
+ for(i=player[currentPlayer].numCards-1;i>=0;i--)
+ {
+ Bitmap bitmap = bitmapCards[player[currentPlayer].cardValues[i]];
+ if(Box {
+ xyPositions[currentPlayer].x + (OFFSETTER1 * i),
+ (player[currentPlayer].cardLifted[i] ? (xyPositions[currentPlayer].y - OFFSETTER2 - 20) :(xyPositions[currentPlayer].y - OFFSETTER2)),
+ bitmap.width + (xyPositions[currentPlayer].x + OFFSETTER1 * i),
+ bitmap.height + (player[currentPlayer].cardLifted[i] ? (xyPositions[currentPlayer].y - OFFSETTER2 - 20) : (xyPositions[currentPlayer].y - OFFSETTER2))
+ }.IsPointInside(Point{x,y}) && drawButton[currentPlayer].disabled)
+
+ {
+ dragCard = player[currentPlayer].cardValues[i];
+ cardToReposition = i;
+ width = bitmap.width;
+ height = bitmap.height;
+ xCursorPositionAtCard = (xyPositions[currentPlayer].x + (OFFSETTER1 * i)) - x;
+ yCursorPositionAtCard = (player[currentPlayer].cardLifted[i] ?
+ (xyPositions[currentPlayer].y - OFFSETTER2 - y - 20) :
+ (xyPositions[currentPlayer].y - OFFSETTER2 - y));
+ flagButtonDown = true;
+ OnMouseMove(x,y,mods);
+ break;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ bool OnRightButtonUp(int x, int y, Modifiers mods)
+ {
+ Bitmap bitmap = cardBack;
+ int swapCard,dest,source,i;
+ Box boxPlayerCards={xyPositions[currentPlayer].x,xyPositions[currentPlayer].y - OFFSETTER2,
+ xyPositions[currentPlayer].x + player[currentPlayer].numCards * OFFSETTER1 + bitmap.width,
+ xyPositions[currentPlayer].y - OFFSETTER2 + bitmap.height};
+ Box boxCard = {x + xCursorPositionAtCard,y + yCursorPositionAtCard, x + xCursorPositionAtCard,y + yCursorPositionAtCard + height - 1};
+
+ if(flagButtonDown)
+ {
+ if(boxCard.Overlap(boxPlayerCards))
+ {
+ swapCard = (x + xCursorPositionAtCard >= player[currentPlayer].numCards * 15 + xyPositions[currentPlayer].x) ?
+ (player[currentPlayer].numCards-1) : ((x + xCursorPositionAtCard - xyPositions[currentPlayer].x) / 15);
+ if(cardToReposition > swapCard)
+ {
+ dest = swapCard + 1;
+ MoveBytes(&player[currentPlayer].cardValues[dest],
+ &player[currentPlayer].cardValues[swapCard],(cardToReposition - swapCard) * sizeof(int));
+ player[currentPlayer].cardValues[swapCard] = dragCard;
+ //player[currentPlayer].cardLifted[swapCard] = false;
+ }
+ else
+ {
+ dest = cardToReposition;
+ source = cardToReposition + 1;
+ MoveBytes(&player[currentPlayer].cardValues[dest],
+ &player[currentPlayer].cardValues[source],(swapCard - cardToReposition) * sizeof(int));
+ player[currentPlayer].cardValues[swapCard] = dragCard;
+ //player[currentPlayer].cardLifted[swapCard] = false;
+ }
+
+ }
+
+ for(i=0;i<player[currentPlayer].numCards;i++)
+ {
+ player[currentPlayer].cardLifted[i] = false;
+ }
+
+ flagButtonDown = false;
+ ReleaseCapture();
+ Update(null);
+ }
+ return true;
+ }
+}
+
+TongIts tongIts {};