renaming and moving samples around
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5300 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
1
demos/forty/.cvsignore
Normal file
1
demos/forty/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
|
21
demos/forty/Makefile.in
Normal file
21
demos/forty/Makefile.in
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# File: Makefile.in
|
||||
# Author: Julian Smart
|
||||
# Created: 1998
|
||||
# Updated:
|
||||
# Copyright: (c) 1998 Julian Smart
|
||||
#
|
||||
# "%W% %G%"
|
||||
#
|
||||
# Makefile for forty example (UNIX).
|
||||
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = ../..
|
||||
program_dir = samples/forty
|
||||
|
||||
PROGRAM=forty
|
||||
|
||||
OBJECTS=$(PROGRAM).o canvas.o card.o game.o pile.o playerdg.o scoredg.o scorefil.o
|
||||
|
||||
include ../../src/makeprog.env
|
||||
|
253
demos/forty/canvas.cpp
Normal file
253
demos/forty/canvas.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: canvas.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "forty.h"
|
||||
#include "card.h"
|
||||
#include "game.h"
|
||||
#include "scorefil.h"
|
||||
#include "playerdg.h"
|
||||
#include "canvas.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(FortyCanvas, wxScrolledWindow)
|
||||
EVT_MOUSE_EVENTS(FortyCanvas::OnMouseEvent)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
FortyCanvas::FortyCanvas(wxWindow* parent, int x, int y, int w, int h) :
|
||||
wxScrolledWindow(parent, -1, wxPoint(x, y), wxSize(w, h)),
|
||||
m_helpingHand(TRUE),
|
||||
m_rightBtnUndo(TRUE),
|
||||
m_playerDialog(0),
|
||||
m_leftBtnDown(FALSE)
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
m_font = wxTheFontList->FindOrCreateFont(12, wxROMAN, wxNORMAL, wxNORMAL);
|
||||
#else
|
||||
m_font = wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxNORMAL);
|
||||
#endif
|
||||
SetBackgroundColour(FortyApp::BackgroundColour());
|
||||
|
||||
m_handCursor = new wxCursor(wxCURSOR_HAND);
|
||||
m_arrowCursor = new wxCursor(wxCURSOR_ARROW);
|
||||
|
||||
wxString name = wxTheApp->GetAppName();
|
||||
if (name.Length() <= 0) name = "forty";
|
||||
m_scoreFile = new ScoreFile(name);
|
||||
m_game = new Game(0, 0, 0);
|
||||
m_game->Deal();
|
||||
}
|
||||
|
||||
|
||||
FortyCanvas::~FortyCanvas()
|
||||
{
|
||||
UpdateScores();
|
||||
delete m_game;
|
||||
delete m_scoreFile;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Write the current player's score back to the score file
|
||||
*/
|
||||
void FortyCanvas::UpdateScores()
|
||||
{
|
||||
if (m_player.Length() > 0 && m_scoreFile && m_game)
|
||||
{
|
||||
m_scoreFile->WritePlayersScore(
|
||||
m_player,
|
||||
m_game->GetNumWins(),
|
||||
m_game->GetNumGames(),
|
||||
m_game->GetScore()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FortyCanvas::OnDraw(wxDC& dc)
|
||||
{
|
||||
dc.SetFont(* m_font);
|
||||
m_game->Redraw(dc);
|
||||
|
||||
// if player name not set (and selection dialog is not displayed)
|
||||
// then ask the player for their name
|
||||
if (m_player.Length() == 0 && !m_playerDialog)
|
||||
{
|
||||
m_playerDialog = new PlayerSelectionDialog(this, m_scoreFile);
|
||||
m_playerDialog->ShowModal();
|
||||
m_player = m_playerDialog->GetPlayersName();
|
||||
if (m_player.Length() > 0)
|
||||
{
|
||||
// user entered a name - lookup their score
|
||||
int wins, games, score;
|
||||
m_scoreFile->ReadPlayersScore(m_player, wins, games, score);
|
||||
m_game->NewPlayer(wins, games, score);
|
||||
m_game->DisplayScore(dc);
|
||||
m_playerDialog->Destroy();
|
||||
m_playerDialog = 0;
|
||||
Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
// user cancelled the dialog - exit the app
|
||||
((wxFrame*)GetParent())->Close(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Called when the main frame is closed
|
||||
*/
|
||||
bool FortyCanvas::OnCloseCanvas()
|
||||
{
|
||||
if (m_game->InPlay() &&
|
||||
wxMessageBox("Are you sure you want to\nabandon the current game?",
|
||||
"Warning", wxYES_NO | wxICON_QUESTION) == wxNO)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void FortyCanvas::OnMouseEvent(wxMouseEvent& event)
|
||||
{
|
||||
int mouseX = (int)event.GetX();
|
||||
int mouseY = (int)event.GetY();
|
||||
|
||||
wxClientDC dc(this);
|
||||
PrepareDC(dc);
|
||||
dc.SetFont(* m_font);
|
||||
|
||||
if (event.LeftDClick())
|
||||
{
|
||||
if (m_leftBtnDown)
|
||||
{
|
||||
m_leftBtnDown = FALSE;
|
||||
ReleaseMouse();
|
||||
m_game->LButtonUp(dc, mouseX, mouseY);
|
||||
}
|
||||
m_game->LButtonDblClk(dc, mouseX, mouseY);
|
||||
}
|
||||
else if (event.LeftDown())
|
||||
{
|
||||
if (!m_leftBtnDown)
|
||||
{
|
||||
m_leftBtnDown = TRUE;
|
||||
CaptureMouse();
|
||||
m_game->LButtonDown(dc, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
else if (event.LeftUp())
|
||||
{
|
||||
if (m_leftBtnDown)
|
||||
{
|
||||
m_leftBtnDown = FALSE;
|
||||
ReleaseMouse();
|
||||
m_game->LButtonUp(dc, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
else if (event.RightDown() && !event.LeftIsDown())
|
||||
{
|
||||
// only allow right button undo if m_rightBtnUndo is TRUE
|
||||
if (m_rightBtnUndo)
|
||||
{
|
||||
if (event.ControlDown() || event.ShiftDown())
|
||||
{
|
||||
m_game->Redo(dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_game->Undo(dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.Dragging())
|
||||
{
|
||||
m_game->MouseMove(dc, mouseX, mouseY);
|
||||
}
|
||||
|
||||
if (!event.LeftIsDown())
|
||||
{
|
||||
SetCursorStyle(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
void FortyCanvas::SetCursorStyle(int x, int y)
|
||||
{
|
||||
if (m_game->HaveYouWon())
|
||||
{
|
||||
if (wxMessageBox("Do you wish to play again?",
|
||||
"Well Done, You have won!", wxYES_NO | wxICON_QUESTION) == wxYES)
|
||||
{
|
||||
m_game->Deal();
|
||||
|
||||
wxClientDC dc(this);
|
||||
PrepareDC(dc);
|
||||
dc.SetFont(* m_font);
|
||||
m_game->Redraw(dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// user cancelled the dialog - exit the app
|
||||
((wxFrame*)GetParent())->Close(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Only set cursor to a hand if 'helping hand' is enabled and
|
||||
// the card under the cursor can go somewhere
|
||||
if (m_game->CanYouGo(x, y) && m_helpingHand)
|
||||
{
|
||||
SetCursor(* m_handCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCursor(* m_arrowCursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FortyCanvas::NewGame()
|
||||
{
|
||||
m_game->Deal();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void FortyCanvas::Undo()
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
PrepareDC(dc);
|
||||
dc.SetFont(* m_font);
|
||||
m_game->Undo(dc);
|
||||
}
|
||||
|
||||
void FortyCanvas::Redo()
|
||||
{
|
||||
wxClientDC dc(this);
|
||||
PrepareDC(dc);
|
||||
dc.SetFont(* m_font);
|
||||
m_game->Redo(dc);
|
||||
}
|
56
demos/forty/canvas.h
Normal file
56
demos/forty/canvas.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: canvas.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _CANVAS_H_
|
||||
#define _CANVAS_H_
|
||||
|
||||
class Card;
|
||||
class Game;
|
||||
class ScoreFile;
|
||||
class PlayerSelectionDialog;
|
||||
|
||||
class FortyCanvas: public wxScrolledWindow
|
||||
{
|
||||
public:
|
||||
FortyCanvas(wxWindow* parent, int x, int y, int w, int h);
|
||||
virtual ~FortyCanvas();
|
||||
|
||||
virtual void OnDraw(wxDC& dc);
|
||||
bool OnCloseCanvas();
|
||||
void OnMouseEvent(wxMouseEvent& event);
|
||||
void SetCursorStyle(int x, int y);
|
||||
|
||||
void NewGame();
|
||||
void Undo();
|
||||
void Redo();
|
||||
|
||||
ScoreFile* GetScoreFile() const { return m_scoreFile; }
|
||||
void UpdateScores();
|
||||
void EnableHelpingHand(bool enable) { m_helpingHand = enable; }
|
||||
void EnableRightButtonUndo(bool enable) { m_rightBtnUndo = enable; }
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
private:
|
||||
wxFont* m_font;
|
||||
Game* m_game;
|
||||
ScoreFile* m_scoreFile;
|
||||
wxCursor* m_arrowCursor;
|
||||
wxCursor* m_handCursor;
|
||||
bool m_helpingHand;
|
||||
bool m_rightBtnUndo;
|
||||
wxString m_player;
|
||||
PlayerSelectionDialog* m_playerDialog;
|
||||
bool m_leftBtnDown;
|
||||
};
|
||||
|
||||
#endif
|
358
demos/forty/card.cpp
Normal file
358
demos/forty/card.cpp
Normal file
@@ -0,0 +1,358 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: card.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description
|
||||
//| A class for drawing playing cards.
|
||||
//| Currently assumes that the card symbols have been
|
||||
//| loaded into hbmap_symbols and the pictures for the
|
||||
//| Jack, Queen and King have been loaded into
|
||||
//| hbmap_pictures.
|
||||
//+-------------------------------------------------------------+
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "forty.h"
|
||||
#include "card.h"
|
||||
|
||||
#if defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__)
|
||||
#include "pictures.xpm"
|
||||
#include "symbols.xbm"
|
||||
#endif
|
||||
|
||||
wxBitmap* Card::m_pictureBmap = 0;
|
||||
wxBitmap* Card::m_symbolBmap = 0;
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Card::Card() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Constructor for a playing card. |
|
||||
//| Checks that the value is in the range 1..52 and then |
|
||||
//| initialises the suit, colour, pipValue and wayUp. |
|
||||
//+-------------------------------------------------------------+
|
||||
Card::Card(int value, WayUp way_up) :
|
||||
m_wayUp(way_up)
|
||||
{
|
||||
if (!m_symbolBmap)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
m_symbolBmap = new wxBitmap("CardSymbols", wxBITMAP_TYPE_BMP_RESOURCE);
|
||||
#else
|
||||
m_symbolBmap = new wxBitmap(Symbols_bits, Symbols_width, Symbols_height);
|
||||
#endif
|
||||
if (!m_symbolBmap->Ok())
|
||||
{
|
||||
::wxMessageBox("Failed to load bitmap CardSymbols", "Error");
|
||||
}
|
||||
}
|
||||
if (!m_pictureBmap)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
m_pictureBmap = new wxBitmap("CardPictures", wxBITMAP_TYPE_BMP_RESOURCE);
|
||||
#else
|
||||
m_pictureBmap = new wxBitmap(Pictures);
|
||||
#endif
|
||||
if (!m_pictureBmap->Ok())
|
||||
{
|
||||
::wxMessageBox("Failed to load bitmap CardPictures", "Error");
|
||||
}
|
||||
}
|
||||
|
||||
if (value >= 1 && value <= PackSize)
|
||||
{
|
||||
switch ((value - 1) / 13)
|
||||
{
|
||||
case 0:
|
||||
m_suit = clubs;
|
||||
m_colour = black;
|
||||
break;
|
||||
case 1:
|
||||
m_suit = diamonds;
|
||||
m_colour = red;
|
||||
break;
|
||||
case 2:
|
||||
m_suit = hearts;
|
||||
m_colour = red;
|
||||
break;
|
||||
case 3:
|
||||
m_suit = spades;
|
||||
m_colour = black;
|
||||
break;
|
||||
}
|
||||
m_pipValue = 1 + (value - 1) % 13;
|
||||
m_status = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = FALSE;
|
||||
}
|
||||
} // Card::Card()
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Card::~Card() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Destructor - nothing to do at present. |
|
||||
//+-------------------------------------------------------------+
|
||||
Card::~Card()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Card::Erase() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Erase the card at (x, y) by drawing a rectangle in the |
|
||||
//| background colour. |
|
||||
//+-------------------------------------------------------------+
|
||||
void Card::Erase(wxDC& dc, int x, int y)
|
||||
{
|
||||
wxPen* pen = wxThePenList->FindOrCreatePen(
|
||||
FortyApp::BackgroundColour(),
|
||||
1,
|
||||
wxSOLID
|
||||
);
|
||||
dc.SetPen(* pen);
|
||||
dc.SetBrush(FortyApp::BackgroundBrush());
|
||||
dc.DrawRectangle(x, y, CardWidth, CardHeight);
|
||||
} // Card::Erase()
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Card::Draw() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Draw the card at (x, y). |
|
||||
//| If the card is facedown draw the back of the card. |
|
||||
//| If the card is faceup draw the front of the card. |
|
||||
//| Cards are not held in bitmaps, instead they are drawn |
|
||||
//| from their constituent parts when required. |
|
||||
//| hbmap_symbols contains large and small suit symbols and |
|
||||
//| pip values. These are copied to the appropriate part of |
|
||||
//| the card. Picture cards use the pictures defined in |
|
||||
//| hbmap_pictures. Note that only one picture is defined |
|
||||
//| for the Jack, Queen and King, unlike a real pack where |
|
||||
//| each suit is different. |
|
||||
//| |
|
||||
//| WARNING: |
|
||||
//| The locations of these symbols is 'hard-wired' into the |
|
||||
//| code. Editing the bitmaps or the numbers below will |
|
||||
//| result in the wrong symbols being displayed. |
|
||||
//+-------------------------------------------------------------+
|
||||
void Card::Draw(wxDC& dc, int x, int y)
|
||||
{
|
||||
wxBrush backgroundBrush( dc.GetBackground() );
|
||||
dc.SetBrush(* wxWHITE_BRUSH);
|
||||
dc.SetPen(* wxBLACK_PEN);
|
||||
dc.DrawRoundedRectangle(x, y, CardWidth, CardHeight, 4);
|
||||
if (m_wayUp == facedown)
|
||||
{
|
||||
dc.SetBackground(* wxRED_BRUSH);
|
||||
dc.SetBackgroundMode(wxSOLID);
|
||||
wxBrush* brush = wxTheBrushList->FindOrCreateBrush(
|
||||
"BLACK", wxCROSSDIAG_HATCH
|
||||
);
|
||||
dc.SetBrush(* brush);
|
||||
|
||||
dc.DrawRoundedRectangle(
|
||||
x + 4, y + 4,
|
||||
CardWidth - 8, CardHeight - 8,
|
||||
2
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMemoryDC memoryDC;
|
||||
memoryDC.SelectObject(* m_symbolBmap);
|
||||
|
||||
// dc.SetBackgroundMode(wxTRANSPARENT);
|
||||
|
||||
dc.SetTextBackground(*wxWHITE);
|
||||
switch (m_suit)
|
||||
{
|
||||
case spades:
|
||||
case clubs:
|
||||
dc.SetTextForeground(*wxBLACK);
|
||||
break;
|
||||
case diamonds:
|
||||
case hearts:
|
||||
dc.SetTextForeground(*wxRED);
|
||||
break;
|
||||
}
|
||||
// Draw the value
|
||||
dc.Blit(x + 3, y + 3, 6, 7,
|
||||
&memoryDC, 6 * (m_pipValue - 1), 36, wxCOPY);
|
||||
dc.Blit(x + CardWidth - 9, y + CardHeight - 11, 6, 7,
|
||||
&memoryDC, 6 * (m_pipValue - 1), 43, wxCOPY);
|
||||
|
||||
// Draw the pips
|
||||
dc.Blit(x + 11, y + 3, 7, 7,
|
||||
&memoryDC, 7 * m_suit, 0, wxCOPY);
|
||||
dc.Blit(x + CardWidth - 17, y + CardHeight - 11, 7, 7,
|
||||
&memoryDC, 7 * m_suit, 7, wxCOPY);
|
||||
|
||||
switch (m_pipValue)
|
||||
{
|
||||
case 1:
|
||||
dc.Blit(x - 5 + CardWidth / 2, y - 5 + CardHeight / 2, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
dc.Blit(x - 5 + CardWidth / 2, y - 5 + CardHeight / 2, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
case 2:
|
||||
dc.Blit(x - 5 + CardWidth / 2,
|
||||
y - 5 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 2,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
dc.Blit(x - 5 + CardWidth / 2, y - 5 + CardHeight / 2, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
case 4:
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
dc.Blit(x - 5 + 5 * CardWidth / 10,
|
||||
y - 5 + 5 * CardHeight / 8, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
case 7:
|
||||
dc.Blit(x - 5 + 5 * CardWidth / 10,
|
||||
y - 5 + 3 * CardHeight / 8, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
case 6:
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + CardHeight / 2, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + CardHeight / 2, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
dc.Blit(x - 5 + CardWidth / 2,
|
||||
y - 5 + 2 * CardHeight / 3, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
case 9:
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 6 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 6 + 5 * CardHeight / 12, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + 7 * CardHeight / 12, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 4,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 6 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 6 + 5 * CardHeight / 12, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + 7 * CardHeight / 12, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
dc.Blit(x - 5 + 3 * CardWidth / 4,
|
||||
y - 5 + 3 * CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
dc.Blit(x - 5 + CardWidth / 2,
|
||||
y - 5 + CardHeight / 3, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
break;
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
memoryDC.SelectObject(* m_pictureBmap);
|
||||
dc.Blit(x + 5, y - 5 + CardHeight / 4, 40, 45,
|
||||
&memoryDC, 40 * (m_pipValue - 11), 0, wxCOPY);
|
||||
memoryDC.SelectObject(* m_symbolBmap);
|
||||
dc.Blit(x + 32, y - 3 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 14, wxCOPY);
|
||||
dc.Blit(x + 7, y + 27 + CardHeight / 4, 11, 11,
|
||||
&memoryDC, 11 * m_suit, 25, wxCOPY);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
dc.SetBackground( backgroundBrush );
|
||||
} // Card:Draw()
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Card::DrawNullCard() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Draws the outline of a card at (x, y). |
|
||||
//| Used to draw place holders for empty piles of cards. |
|
||||
//+-------------------------------------------------------------+
|
||||
void Card::DrawNullCard(wxDC& dc, int x, int y)
|
||||
{
|
||||
wxPen* pen = wxThePenList->FindOrCreatePen(FortyApp::TextColour(), 1, wxSOLID);
|
||||
dc.SetBrush(FortyApp::BackgroundBrush());
|
||||
dc.SetPen(*pen);
|
||||
dc.DrawRoundedRectangle(x, y, CardWidth, CardHeight, 4);
|
||||
} // Card::DrawNullCard()
|
||||
|
||||
|
65
demos/forty/card.h
Normal file
65
demos/forty/card.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: card.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| A class for drawing playing cards. |
|
||||
//| InitCards() must be called before using the Card class, |
|
||||
//| otherwise the card bitmaps will not be loaded. |
|
||||
//| CloseCards() must be called before terminating the |
|
||||
//| program so that the bitmaps are deleted and the memory |
|
||||
//| given back to Windows. |
|
||||
//+-------------------------------------------------------------+
|
||||
#ifndef _CARD_H_
|
||||
#define _CARD_H_
|
||||
|
||||
// Constants
|
||||
const int PackSize = 52;
|
||||
const int CardWidth = 50;
|
||||
const int CardHeight = 70;
|
||||
|
||||
// Data types
|
||||
enum Suit { clubs = 0, diamonds = 1, hearts = 2, spades = 3 };
|
||||
enum SuitColour { red = 0, black = 1 };
|
||||
enum WayUp { faceup, facedown };
|
||||
|
||||
|
||||
//--------------------------------//
|
||||
// A class defining a single card //
|
||||
//--------------------------------//
|
||||
class Card {
|
||||
public:
|
||||
Card(int value, WayUp way_up = facedown);
|
||||
virtual ~Card();
|
||||
|
||||
void Draw(wxDC& pDC, int x, int y);
|
||||
static void DrawNullCard(wxDC& pDC, int x, int y); // Draw card place-holder
|
||||
void Erase(wxDC& pDC, int x, int y);
|
||||
|
||||
void TurnCard(WayUp way_up = faceup) { m_wayUp = way_up; }
|
||||
WayUp GetWayUp() const { return m_wayUp; }
|
||||
int GetPipValue() const { return m_pipValue; }
|
||||
Suit GetSuit() const { return m_suit; }
|
||||
SuitColour GetColour() const { return m_colour; }
|
||||
|
||||
private:
|
||||
Suit m_suit;
|
||||
int m_pipValue; // in the range 1 (Ace) to 13 (King)
|
||||
SuitColour m_colour; // red or black
|
||||
bool m_status;
|
||||
WayUp m_wayUp;
|
||||
|
||||
static wxBitmap* m_symbolBmap;
|
||||
static wxBitmap* m_pictureBmap;
|
||||
};
|
||||
|
||||
#endif // _CARD_H_
|
BIN
demos/forty/cards.ico
Normal file
BIN
demos/forty/cards.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
271
demos/forty/forty.cpp
Normal file
271
demos/forty/forty.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: forty.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "canvas.h"
|
||||
#include "forty.h"
|
||||
#include "scoredg.h"
|
||||
#ifdef wx_x
|
||||
#include "cards.xbm"
|
||||
#endif
|
||||
|
||||
class FortyFrame: public wxFrame
|
||||
{
|
||||
public:
|
||||
FortyFrame(wxFrame* frame, char* title, int x, int y, int w, int h);
|
||||
virtual ~FortyFrame();
|
||||
|
||||
void OnCloseWindow(wxCloseEvent& event);
|
||||
|
||||
// Menu callbacks
|
||||
void NewGame(wxCommandEvent& event);
|
||||
void Exit(wxCommandEvent& event);
|
||||
void About(wxCommandEvent& event);
|
||||
void Undo(wxCommandEvent& event);
|
||||
void Redo(wxCommandEvent& event);
|
||||
void Scores(wxCommandEvent& event);
|
||||
void ToggleRightButtonUndo(wxCommandEvent& event);
|
||||
void ToggleHelpingHand(wxCommandEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
private:
|
||||
enum MenuCommands { NEW_GAME = 10, SCORES, EXIT,
|
||||
UNDO, REDO,
|
||||
RIGHT_BUTTON_UNDO, HELPING_HAND,
|
||||
ABOUT };
|
||||
|
||||
wxMenuBar* m_menuBar;
|
||||
FortyCanvas* m_canvas;
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(FortyFrame, wxFrame)
|
||||
EVT_MENU(NEW_GAME, FortyFrame::NewGame)
|
||||
EVT_MENU(EXIT, FortyFrame::Exit)
|
||||
EVT_MENU(ABOUT, FortyFrame::About)
|
||||
EVT_MENU(UNDO, FortyFrame::Undo)
|
||||
EVT_MENU(REDO, FortyFrame::Redo)
|
||||
EVT_MENU(SCORES, FortyFrame::Scores)
|
||||
EVT_MENU(RIGHT_BUTTON_UNDO, FortyFrame::ToggleRightButtonUndo)
|
||||
EVT_MENU(HELPING_HAND, FortyFrame::ToggleHelpingHand)
|
||||
EVT_CLOSE(FortyFrame::OnCloseWindow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
// Create a new application object
|
||||
IMPLEMENT_APP (FortyApp)
|
||||
|
||||
wxColour* FortyApp::m_backgroundColour = 0;
|
||||
wxColour* FortyApp::m_textColour = 0;
|
||||
wxBrush* FortyApp::m_backgroundBrush = 0;
|
||||
|
||||
bool FortyApp::OnInit()
|
||||
{
|
||||
FortyFrame* frame = new FortyFrame(
|
||||
0,
|
||||
"Forty Thieves",
|
||||
-1, -1, 668, 510
|
||||
);
|
||||
|
||||
// Show the frame
|
||||
frame->Show(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const wxColour& FortyApp::BackgroundColour()
|
||||
{
|
||||
if (!m_backgroundColour)
|
||||
{
|
||||
m_backgroundColour = new wxColour(0, 128, 0);
|
||||
}
|
||||
|
||||
return *m_backgroundColour;
|
||||
}
|
||||
|
||||
const wxBrush& FortyApp::BackgroundBrush()
|
||||
{
|
||||
if (!m_backgroundBrush)
|
||||
{
|
||||
m_backgroundBrush = new wxBrush(BackgroundColour(), wxSOLID);
|
||||
}
|
||||
|
||||
return *m_backgroundBrush;
|
||||
}
|
||||
|
||||
const wxColour& FortyApp::TextColour()
|
||||
{
|
||||
if (!m_textColour)
|
||||
{
|
||||
m_textColour = new wxColour("BLACK");
|
||||
}
|
||||
|
||||
return *m_textColour;
|
||||
}
|
||||
|
||||
// My frame constructor
|
||||
FortyFrame::FortyFrame(wxFrame* frame, char* title, int x, int y, int w, int h):
|
||||
wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
// we need this in order to allow the about menu relocation, since ABOUT is not the default id of the about menu
|
||||
wxApp::s_macAboutMenuItemId = ABOUT ;
|
||||
#endif
|
||||
// set the icon
|
||||
#ifdef __WXMSW__
|
||||
SetIcon(wxIcon("CardsIcon"));
|
||||
#else
|
||||
#ifdef GTK_TBD
|
||||
SetIcon(wxIcon(Cards_bits, Cards_width, Cards_height));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Make a menu bar
|
||||
wxMenu* gameMenu = new wxMenu;
|
||||
gameMenu->Append(NEW_GAME, "&New", "Start a new game");
|
||||
gameMenu->Append(SCORES, "&Scores...", "Displays scores");
|
||||
gameMenu->Append(EXIT, "E&xit", "Exits Forty Thieves");
|
||||
|
||||
wxMenu* editMenu = new wxMenu;
|
||||
editMenu->Append(UNDO, "&Undo", "Undo the last move");
|
||||
editMenu->Append(REDO, "&Redo", "Redo a move that has been undone");
|
||||
|
||||
wxMenu* optionsMenu = new wxMenu;
|
||||
optionsMenu->Append(RIGHT_BUTTON_UNDO,
|
||||
"&Right button undo",
|
||||
"Enables/disables right mouse button undo and redo",
|
||||
TRUE
|
||||
);
|
||||
optionsMenu->Append(HELPING_HAND,
|
||||
"&Helping hand",
|
||||
"Enables/disables hand cursor when a card can be moved",
|
||||
TRUE
|
||||
);
|
||||
optionsMenu->Check(HELPING_HAND, TRUE);
|
||||
optionsMenu->Check(RIGHT_BUTTON_UNDO, TRUE);
|
||||
|
||||
wxMenu* helpMenu = new wxMenu;
|
||||
helpMenu->Append(ABOUT, "&About", "Displays program version information");
|
||||
|
||||
m_menuBar = new wxMenuBar;
|
||||
m_menuBar->Append(gameMenu, "&Game");
|
||||
m_menuBar->Append(editMenu, "&Edit");
|
||||
m_menuBar->Append(optionsMenu, "&Options");
|
||||
m_menuBar->Append(helpMenu, "&Help");
|
||||
|
||||
SetMenuBar(m_menuBar);
|
||||
|
||||
m_canvas = new FortyCanvas(this, 0, 0, 400, 400);
|
||||
wxLayoutConstraints* constr = new wxLayoutConstraints;
|
||||
constr->left.SameAs(this, wxLeft);
|
||||
constr->top.SameAs(this, wxTop);
|
||||
constr->right.SameAs(this, wxRight);
|
||||
constr->height.SameAs(this, wxHeight);
|
||||
m_canvas->SetConstraints(constr);
|
||||
|
||||
CreateStatusBar();
|
||||
}
|
||||
|
||||
FortyFrame::~FortyFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void FortyFrame::OnCloseWindow(wxCloseEvent& event)
|
||||
{
|
||||
if (m_canvas->OnCloseCanvas() )
|
||||
{
|
||||
this->Destroy();
|
||||
}
|
||||
else
|
||||
event.Veto();
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::NewGame(wxCommandEvent&)
|
||||
{
|
||||
m_canvas->NewGame();
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::Exit(wxCommandEvent&)
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
// wxGTK doesn't call OnClose() so we do it here
|
||||
// if (OnClose())
|
||||
#endif
|
||||
Close(TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::About(wxCommandEvent&)
|
||||
{
|
||||
wxMessageBox(
|
||||
"Forty Thieves\n\n"
|
||||
"A freeware program using the wxWindows\n"
|
||||
"portable C++ GUI toolkit.\n"
|
||||
"http://web.ukonline.co.uk/julian.smart/wxwin\n"
|
||||
"http://www.freiburg.linux.de/~wxxt\n\n"
|
||||
"Author: Chris Breeze (c) 1992-1998\n"
|
||||
"email: chris.breeze@iname.com",
|
||||
"About Forty Thieves",
|
||||
wxOK, this
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::Undo(wxCommandEvent&)
|
||||
{
|
||||
m_canvas->Undo();
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::Redo(wxCommandEvent&)
|
||||
{
|
||||
m_canvas->Redo();
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::Scores(wxCommandEvent&)
|
||||
{
|
||||
m_canvas->UpdateScores();
|
||||
ScoreDialog scores(this, m_canvas->GetScoreFile());
|
||||
scores.Display();
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::ToggleRightButtonUndo(wxCommandEvent& event)
|
||||
{
|
||||
bool checked = m_menuBar->IsChecked(event.GetId());
|
||||
m_canvas->EnableRightButtonUndo(checked);
|
||||
}
|
||||
|
||||
void
|
||||
FortyFrame::ToggleHelpingHand(wxCommandEvent& event)
|
||||
{
|
||||
bool checked = m_menuBar->IsChecked(event.GetId());
|
||||
m_canvas->EnableHelpingHand(checked);
|
||||
}
|
8
demos/forty/forty.def
Normal file
8
demos/forty/forty.def
Normal file
@@ -0,0 +1,8 @@
|
||||
NAME Forty
|
||||
DESCRIPTION 'Forty Thieves'
|
||||
EXETYPE WINDOWS
|
||||
STUB 'WINSTUB.EXE'
|
||||
CODE PRELOAD MOVEABLE DISCARDABLE
|
||||
DATA PRELOAD MOVEABLE MULTIPLE
|
||||
HEAPSIZE 4048
|
||||
STACKSIZE 16000
|
31
demos/forty/forty.h
Normal file
31
demos/forty/forty.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: forty.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _FORTY_H_
|
||||
#define _FORTY_H_
|
||||
|
||||
class FortyApp: public wxApp
|
||||
{
|
||||
public:
|
||||
bool OnInit();
|
||||
|
||||
static const wxColour& BackgroundColour();
|
||||
static const wxColour& TextColour();
|
||||
static const wxBrush& BackgroundBrush();
|
||||
|
||||
private:
|
||||
static wxColour* m_backgroundColour;
|
||||
static wxColour* m_textColour;
|
||||
static wxBrush* m_backgroundBrush;
|
||||
};
|
||||
|
||||
#endif
|
6
demos/forty/forty.rc
Normal file
6
demos/forty/forty.rc
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "wx/msw/wx.rc"
|
||||
|
||||
CardsIcon ICON "cards.ico"
|
||||
CardPictures BITMAP "pictures.bmp"
|
||||
CardSymbols BITMAP "symbols.bmp"
|
||||
|
944
demos/forty/game.cpp
Normal file
944
demos/forty/game.cpp
Normal file
@@ -0,0 +1,944 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: game.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "forty.h"
|
||||
#include "game.h"
|
||||
|
||||
Game::Game(int wins, int games, int score) :
|
||||
m_inPlay(FALSE),
|
||||
m_moveIndex(0),
|
||||
m_redoIndex(0),
|
||||
m_bmap(0),
|
||||
m_bmapCard(0)
|
||||
{
|
||||
int i;
|
||||
|
||||
m_pack = new Pack(2, 2 + 4 * (CardHeight + 2));
|
||||
srand(time(0));
|
||||
|
||||
for (i = 0; i < 5; i++) m_pack->Shuffle();
|
||||
|
||||
m_discard = new Discard(2, 2 + 5 * (CardHeight + 2));
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
m_foundations[i] = new Foundation(2 + (i / 4) * (CardWidth + 2),
|
||||
2 + (i % 4) * (CardHeight + 2));
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
m_bases[i] = new Base(8 + (i + 2) * (CardWidth + 2), 2);
|
||||
}
|
||||
Deal();
|
||||
m_srcPile = 0;
|
||||
m_liftedCard = 0;
|
||||
|
||||
// copy the input parameters for future reference
|
||||
m_numWins = wins;
|
||||
m_numGames = games;
|
||||
m_totalScore = score;
|
||||
m_currentScore = 0;
|
||||
}
|
||||
|
||||
|
||||
// Make sure we delete all objects created by the game object
|
||||
Game::~Game()
|
||||
{
|
||||
int i;
|
||||
|
||||
delete m_pack;
|
||||
delete m_discard;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
delete m_foundations[i];
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
delete m_bases[i];
|
||||
}
|
||||
delete m_bmap;
|
||||
delete m_bmapCard;
|
||||
}
|
||||
|
||||
/*
|
||||
Set the score for a new player.
|
||||
NB: call Deal() first if the new player is to start
|
||||
a new game
|
||||
*/
|
||||
void Game::NewPlayer(int wins, int games, int score)
|
||||
{
|
||||
m_numWins = wins;
|
||||
m_numGames = games;
|
||||
m_totalScore = score;
|
||||
m_currentScore = 0;
|
||||
}
|
||||
|
||||
// Undo the last move
|
||||
void Game::Undo(wxDC& dc)
|
||||
{
|
||||
if (m_moveIndex > 0)
|
||||
{
|
||||
m_moveIndex--;
|
||||
Card* card = m_moves[m_moveIndex].dest->RemoveTopCard(dc);
|
||||
m_moves[m_moveIndex].src->AddCard(dc, card);
|
||||
DisplayScore(dc);
|
||||
}
|
||||
}
|
||||
|
||||
// Redo the last move
|
||||
void Game::Redo(wxDC& dc)
|
||||
{
|
||||
if (m_moveIndex < m_redoIndex)
|
||||
{
|
||||
Card* card = m_moves[m_moveIndex].src->RemoveTopCard(dc);
|
||||
if (m_moves[m_moveIndex].src == m_pack)
|
||||
{
|
||||
m_pack->Redraw(dc);
|
||||
card->TurnCard(faceup);
|
||||
}
|
||||
m_moves[m_moveIndex].dest->AddCard(dc, card);
|
||||
DisplayScore(dc);
|
||||
m_moveIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
void Game::DoMove(wxDC& dc, Pile* src, Pile* dest)
|
||||
{
|
||||
if (m_moveIndex < MaxMoves)
|
||||
{
|
||||
if (src == dest)
|
||||
{
|
||||
wxMessageBox("Game::DoMove() src == dest", "Debug message",
|
||||
wxOK | wxICON_EXCLAMATION);
|
||||
}
|
||||
m_moves[m_moveIndex].src = src;
|
||||
m_moves[m_moveIndex].dest = dest;
|
||||
m_moveIndex++;
|
||||
|
||||
// when we do a move any moves in redo buffer are discarded
|
||||
m_redoIndex = m_moveIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageBox("Game::DoMove() Undo buffer full", "Debug message",
|
||||
wxOK | wxICON_EXCLAMATION);
|
||||
}
|
||||
|
||||
if (!m_inPlay)
|
||||
{
|
||||
m_inPlay = TRUE;
|
||||
m_numGames++;
|
||||
}
|
||||
DisplayScore(dc);
|
||||
}
|
||||
|
||||
|
||||
void Game::DisplayScore(wxDC& dc)
|
||||
{
|
||||
wxColour bgColour = FortyApp::BackgroundColour();
|
||||
wxPen* pen = wxThePenList->FindOrCreatePen(bgColour, 1, wxSOLID);
|
||||
dc.SetTextBackground(bgColour);
|
||||
dc.SetTextForeground(FortyApp::TextColour());
|
||||
dc.SetBrush(FortyApp::BackgroundBrush());
|
||||
dc.SetPen(* pen);
|
||||
|
||||
// count the number of cards in foundations
|
||||
m_currentScore = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_currentScore += m_foundations[i]->GetNumCards();
|
||||
}
|
||||
|
||||
int x, y;
|
||||
m_pack->GetTopCardPos(x, y);
|
||||
x += 12 * CardWidth - 105;
|
||||
|
||||
int w, h;
|
||||
{
|
||||
long width, height;
|
||||
dc.GetTextExtent("Average score:m_x", &width, &height);
|
||||
w = width;
|
||||
h = height;
|
||||
}
|
||||
dc.DrawRectangle(x + w, y, 20, 4 * h);
|
||||
|
||||
char str[80];
|
||||
sprintf(str, "%d", m_currentScore);
|
||||
dc.DrawText("Score:", x, y);
|
||||
dc.DrawText(str, x + w, y);
|
||||
y += h;
|
||||
|
||||
sprintf(str, "%d", m_numGames);
|
||||
dc.DrawText("Games played:", x, y);
|
||||
dc.DrawText(str, x + w, y);
|
||||
y += h;
|
||||
|
||||
sprintf(str, "%d", m_numWins);
|
||||
dc.DrawText("Games won:", x, y);
|
||||
dc.DrawText(str, x + w, y);
|
||||
y += h;
|
||||
|
||||
int average = 0;
|
||||
if (m_numGames > 0)
|
||||
{
|
||||
average = (2 * (m_currentScore + m_totalScore) + m_numGames ) / (2 * m_numGames);
|
||||
}
|
||||
sprintf(str, "%d", average);
|
||||
dc.DrawText("Average score:", x, y);
|
||||
dc.DrawText(str, x + w, y);
|
||||
}
|
||||
|
||||
|
||||
// Shuffle the m_pack and deal the cards
|
||||
void Game::Deal()
|
||||
{
|
||||
int i, j;
|
||||
Card* card;
|
||||
|
||||
// Reset all the piles, the undo buffer and shuffle the m_pack
|
||||
m_moveIndex = 0;
|
||||
m_pack->ResetPile();
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
m_pack->Shuffle();
|
||||
}
|
||||
m_discard->ResetPile();
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
m_bases[i]->ResetPile();
|
||||
}
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
m_foundations[i]->ResetPile();
|
||||
}
|
||||
|
||||
// Deal the initial 40 cards onto the bases
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
for (j = 1; j <= 4; j++)
|
||||
{
|
||||
card = m_pack->RemoveTopCard();
|
||||
card->TurnCard(faceup);
|
||||
m_bases[i]->AddCard(card);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_inPlay)
|
||||
{
|
||||
// player has started the game and then redealt
|
||||
// and so we must add the score for this game to the total score
|
||||
m_totalScore += m_currentScore;
|
||||
}
|
||||
m_currentScore = 0;
|
||||
m_inPlay = FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Redraw the m_pack, discard pile, the bases and the foundations
|
||||
void Game::Redraw(wxDC& dc)
|
||||
{
|
||||
int i;
|
||||
m_pack->Redraw(dc);
|
||||
m_discard->Redraw(dc);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
m_foundations[i]->Redraw(dc);
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
m_bases[i]->Redraw(dc);
|
||||
}
|
||||
DisplayScore(dc);
|
||||
|
||||
if (m_bmap == 0)
|
||||
{
|
||||
m_bmap = new wxBitmap(CardWidth, CardHeight);
|
||||
m_bmapCard = new wxBitmap(CardWidth, CardHeight);
|
||||
|
||||
// Initialise the card bitmap to the background colour
|
||||
wxMemoryDC memoryDC;
|
||||
memoryDC.SelectObject(*m_bmapCard);
|
||||
memoryDC.SetBrush(FortyApp::BackgroundBrush());
|
||||
memoryDC.DrawRectangle(0, 0, CardWidth, CardHeight);
|
||||
memoryDC.SelectObject(*m_bmap);
|
||||
memoryDC.DrawRectangle(0, 0, CardWidth, CardHeight);
|
||||
memoryDC.SelectObject(wxNullBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test to see if the point (x, y) is over the top card of one of the piles
|
||||
// Returns pointer to the pile, or 0 if (x, y) is not over a pile
|
||||
// or the pile is empty
|
||||
Pile* Game::WhichPile(int x, int y)
|
||||
{
|
||||
if (m_pack->GetCard(x, y) &&
|
||||
m_pack->GetCard(x, y) == m_pack->GetTopCard())
|
||||
{
|
||||
return m_pack;
|
||||
}
|
||||
|
||||
if (m_discard->GetCard(x, y) &&
|
||||
m_discard->GetCard(x, y) == m_discard->GetTopCard())
|
||||
{
|
||||
return m_discard;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (m_foundations[i]->GetCard(x, y) &&
|
||||
m_foundations[i]->GetCard(x, y) == m_foundations[i]->GetTopCard())
|
||||
{
|
||||
return m_foundations[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (m_bases[i]->GetCard(x, y) &&
|
||||
m_bases[i]->GetCard(x, y) == m_bases[i]->GetTopCard())
|
||||
{
|
||||
return m_bases[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Left button is pressed - if cursor is over the m_pack then deal a card
|
||||
// otherwise if it is over a card pick it up ready to be dragged - see MouseMove()
|
||||
bool Game::LButtonDown(wxDC& dc, int x, int y)
|
||||
{
|
||||
m_srcPile = WhichPile(x, y);
|
||||
if (m_srcPile == m_pack)
|
||||
{
|
||||
Card* card = m_pack->RemoveTopCard();
|
||||
if (card)
|
||||
{
|
||||
m_pack->Redraw(dc);
|
||||
card->TurnCard(faceup);
|
||||
m_discard->AddCard(dc, card);
|
||||
DoMove(dc, m_pack, m_discard);
|
||||
}
|
||||
m_srcPile = 0;
|
||||
}
|
||||
else if (m_srcPile)
|
||||
{
|
||||
m_srcPile->GetTopCardPos(m_xPos, m_yPos);
|
||||
m_xOffset = m_xPos - x;
|
||||
m_yOffset = m_yPos - y;
|
||||
|
||||
// Copy the area under the card
|
||||
// Initialise the card bitmap to the background colour
|
||||
{
|
||||
wxMemoryDC memoryDC;
|
||||
memoryDC.SelectObject(*m_bmap);
|
||||
m_liftedCard = m_srcPile->RemoveTopCard(memoryDC, m_xPos, m_yPos);
|
||||
}
|
||||
|
||||
// Draw the card in card bitmap ready for blitting onto
|
||||
// the screen
|
||||
{
|
||||
wxMemoryDC memoryDC;
|
||||
memoryDC.SelectObject(*m_bmapCard);
|
||||
m_liftedCard->Draw(memoryDC, 0, 0);
|
||||
}
|
||||
}
|
||||
return m_srcPile != 0;
|
||||
}
|
||||
|
||||
// Called when the left button is double clicked
|
||||
// If a card is under the pointer and it can move elsewhere then move it.
|
||||
// Move onto a foundation as first choice, a populated base as second and
|
||||
// an empty base as third choice.
|
||||
// NB Cards in the m_pack cannot be moved in this way - they aren't in play
|
||||
// yet
|
||||
void Game::LButtonDblClk(wxDC& dc, int x, int y)
|
||||
{
|
||||
Pile* pile = WhichPile(x, y);
|
||||
if (!pile) return;
|
||||
|
||||
// Double click on m_pack is the same as left button down
|
||||
if (pile == m_pack)
|
||||
{
|
||||
LButtonDown(dc, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
Card* card = pile->GetTopCard();
|
||||
|
||||
if (card)
|
||||
{
|
||||
int i;
|
||||
|
||||
// if the card is an ace then try to place it next
|
||||
// to an ace of the same suit
|
||||
if (card->GetPipValue() == 1)
|
||||
{
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
Card* m_topCard;
|
||||
if ((m_topCard = m_foundations[i]->GetTopCard()))
|
||||
{
|
||||
if (m_topCard->GetSuit() == card->GetSuit() &&
|
||||
m_foundations[i + 4] != pile &&
|
||||
m_foundations[i + 4]->GetTopCard() == 0)
|
||||
{
|
||||
pile->RemoveTopCard(dc);
|
||||
m_foundations[i + 4]->AddCard(dc, card);
|
||||
DoMove(dc, pile, m_foundations[i + 4]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try to place the card on a foundation
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
if (m_foundations[i]->AcceptCard(card) && m_foundations[i] != pile)
|
||||
{
|
||||
pile->RemoveTopCard(dc);
|
||||
m_foundations[i]->AddCard(dc, card);
|
||||
DoMove(dc, pile, m_foundations[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// try to place the card on a populated base
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
if (m_bases[i]->AcceptCard(card) &&
|
||||
m_bases[i] != pile &&
|
||||
m_bases[i]->GetTopCard())
|
||||
{
|
||||
pile->RemoveTopCard(dc);
|
||||
m_bases[i]->AddCard(dc, card);
|
||||
DoMove(dc, pile, m_bases[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// try to place the card on any base
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
if (m_bases[i]->AcceptCard(card) && m_bases[i] != pile)
|
||||
{
|
||||
pile->RemoveTopCard(dc);
|
||||
m_bases[i]->AddCard(dc, card);
|
||||
DoMove(dc, pile, m_bases[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test to see whether the game has been won:
|
||||
// i.e. m_pack, discard and bases are empty
|
||||
bool Game::HaveYouWon()
|
||||
{
|
||||
if (m_pack->GetTopCard()) return FALSE;
|
||||
if (m_discard->GetTopCard()) return FALSE;
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
if (m_bases[i]->GetTopCard()) return FALSE;
|
||||
}
|
||||
m_numWins++;
|
||||
m_totalScore += m_currentScore;
|
||||
m_currentScore = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// See whether the card under the cursor can be moved somewhere else
|
||||
// Returns TRUE if it can be moved, FALSE otherwise
|
||||
bool Game::CanYouGo(int x, int y)
|
||||
{
|
||||
Pile* pile = WhichPile(x, y);
|
||||
if (pile && pile != m_pack)
|
||||
{
|
||||
Card* card = pile->GetTopCard();
|
||||
|
||||
if (card)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
if (m_foundations[i]->AcceptCard(card) && m_foundations[i] != pile)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
if (m_bases[i]->GetTopCard() &&
|
||||
m_bases[i]->AcceptCard(card) &&
|
||||
m_bases[i] != pile)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Called when the left button is released after dragging a card
|
||||
// Scan the piles to see if this card overlaps a pile and can be added
|
||||
// to the pile. If the card overlaps more than one pile on which it can be placed
|
||||
// then put it on the nearest pile.
|
||||
void Game::LButtonUp(wxDC& dc, int x, int y)
|
||||
{
|
||||
if (m_srcPile)
|
||||
{
|
||||
// work out the position of the dragged card
|
||||
x += m_xOffset;
|
||||
y += m_yOffset;
|
||||
|
||||
Pile* nearestPile = 0;
|
||||
int distance = (CardHeight + CardWidth) * (CardHeight + CardWidth);
|
||||
|
||||
// find the nearest pile which will accept the card
|
||||
int i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (DropCard(x, y, m_foundations[i], m_liftedCard))
|
||||
{
|
||||
if (m_foundations[i]->CalcDistance(x, y) < distance)
|
||||
{
|
||||
nearestPile = m_foundations[i];
|
||||
distance = nearestPile->CalcDistance(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
if (DropCard(x, y, m_bases[i], m_liftedCard))
|
||||
{
|
||||
if (m_bases[i]->CalcDistance(x, y) < distance)
|
||||
{
|
||||
nearestPile = m_bases[i];
|
||||
distance = nearestPile->CalcDistance(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the area under the card
|
||||
wxMemoryDC memoryDC;
|
||||
memoryDC.SelectObject(*m_bmap);
|
||||
dc.Blit(m_xPos, m_yPos, CardWidth, CardHeight,
|
||||
&memoryDC, 0, 0, wxCOPY);
|
||||
|
||||
// Draw the card in its new position
|
||||
if (nearestPile)
|
||||
{
|
||||
// Add to new pile
|
||||
nearestPile->AddCard(dc, m_liftedCard);
|
||||
if (nearestPile != m_srcPile)
|
||||
{
|
||||
DoMove(dc, m_srcPile, nearestPile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return card to src pile
|
||||
m_srcPile->AddCard(dc, m_liftedCard);
|
||||
}
|
||||
m_srcPile = 0;
|
||||
m_liftedCard = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Game::DropCard(int x, int y, Pile* pile, Card* card)
|
||||
{
|
||||
bool retval = FALSE;
|
||||
if (pile->Overlap(x, y))
|
||||
{
|
||||
if (pile->AcceptCard(card))
|
||||
{
|
||||
retval = TRUE;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void Game::MouseMove(wxDC& dc, int mx, int my)
|
||||
{
|
||||
if (m_liftedCard)
|
||||
{
|
||||
wxMemoryDC memoryDC;
|
||||
memoryDC.SelectObject(*m_bmap);
|
||||
|
||||
int dx = mx + m_xOffset - m_xPos;
|
||||
int dy = my + m_yOffset - m_yPos;
|
||||
|
||||
if (abs(dx) >= CardWidth || abs(dy) >= CardHeight)
|
||||
{
|
||||
// Restore the area under the card
|
||||
dc.Blit(m_xPos, m_yPos, CardWidth, CardHeight,
|
||||
&memoryDC, 0, 0, wxCOPY);
|
||||
|
||||
// Copy the area under the card in the new position
|
||||
memoryDC.Blit(0, 0, CardWidth, CardHeight,
|
||||
&dc, m_xPos + dx, m_yPos + dy, wxCOPY);
|
||||
}
|
||||
else if (dx >= 0)
|
||||
{
|
||||
// dx >= 0
|
||||
dc.Blit(m_xPos, m_yPos, dx, CardHeight, &memoryDC, 0, 0, wxCOPY);
|
||||
if (dy >= 0)
|
||||
{
|
||||
// dy >= 0
|
||||
dc.Blit(m_xPos + dx, m_yPos, CardWidth - dx, dy, &memoryDC, dx, 0, wxCOPY);
|
||||
memoryDC.Blit(0, 0, CardWidth - dx, CardHeight - dy,
|
||||
&memoryDC, dx, dy, wxCOPY);
|
||||
memoryDC.Blit(0, CardHeight - dy, CardWidth - dx, dy,
|
||||
&dc, m_xPos + dx, m_yPos + CardHeight, wxCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dy < 0
|
||||
dc.Blit(m_xPos + dx, m_yPos + dy + CardHeight, CardWidth - dx, -dy,
|
||||
&memoryDC, dx, CardHeight + dy, wxCOPY);
|
||||
memoryDC.Blit(0, -dy, CardWidth - dx, CardHeight + dy,
|
||||
&memoryDC, dx, 0, wxCOPY);
|
||||
memoryDC.Blit(0, 0, CardWidth - dx, -dy,
|
||||
&dc, m_xPos + dx, m_yPos + dy, wxCOPY);
|
||||
}
|
||||
memoryDC.Blit(CardWidth - dx, 0, dx, CardHeight,
|
||||
&dc, m_xPos + CardWidth, m_yPos + dy, wxCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dx < 0
|
||||
dc.Blit(m_xPos + CardWidth + dx, m_yPos, -dx, CardHeight,
|
||||
&memoryDC, CardWidth + dx, 0, wxCOPY);
|
||||
if (dy >= 0)
|
||||
{
|
||||
dc.Blit(m_xPos, m_yPos, CardWidth + dx, dy, &memoryDC, 0, 0, wxCOPY);
|
||||
memoryDC.Blit(-dx, 0, CardWidth + dx, CardHeight - dy,
|
||||
&memoryDC, 0, dy, wxCOPY);
|
||||
memoryDC.Blit(-dx, CardHeight - dy, CardWidth + dx, dy,
|
||||
&dc, m_xPos, m_yPos + CardHeight, wxCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// dy < 0
|
||||
dc.Blit(m_xPos, m_yPos + CardHeight + dy, CardWidth + dx, -dy,
|
||||
&memoryDC, 0, CardHeight + dy, wxCOPY);
|
||||
memoryDC.Blit(-dx, -dy, CardWidth + dx, CardHeight + dy,
|
||||
&memoryDC, 0, 0, wxCOPY);
|
||||
memoryDC.Blit(-dx, 0, CardWidth + dx, -dy,
|
||||
&dc, m_xPos, m_yPos + dy, wxCOPY);
|
||||
}
|
||||
memoryDC.Blit(0, 0, -dx, CardHeight,
|
||||
&dc, m_xPos + dx, m_yPos + dy, wxCOPY);
|
||||
}
|
||||
m_xPos += dx;
|
||||
m_yPos += dy;
|
||||
|
||||
// draw the card in its new position
|
||||
memoryDC.SelectObject(*m_bmapCard);
|
||||
dc.Blit(m_xPos, m_yPos, CardWidth, CardHeight,
|
||||
&memoryDC, 0, 0, wxCOPY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------//
|
||||
// The Pack class: holds the two decks of cards //
|
||||
//----------------------------------------------//
|
||||
Pack::Pack(int x, int y) : Pile(x, y, 0, 0)
|
||||
{
|
||||
for (m_topCard = 0; m_topCard < NumCards; m_topCard++)
|
||||
{
|
||||
m_cards[m_topCard] = new Card(1 + m_topCard / 2, facedown);
|
||||
}
|
||||
m_topCard = NumCards - 1;
|
||||
}
|
||||
|
||||
|
||||
void Pack::Shuffle()
|
||||
{
|
||||
Card* temp[NumCards];
|
||||
int i;
|
||||
|
||||
// Don't try to shuffle an empty m_pack!
|
||||
if (m_topCard < 0) return;
|
||||
|
||||
// Copy the cards into a temporary array. Start by clearing
|
||||
// the array and then copy the card into a random position.
|
||||
// If the position is occupied then find the next lower position.
|
||||
for (i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
temp[i] = 0;
|
||||
}
|
||||
for (i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
int pos = rand() % (m_topCard + 1);
|
||||
while (temp[pos])
|
||||
{
|
||||
pos--;
|
||||
if (pos < 0) pos = m_topCard;
|
||||
}
|
||||
m_cards[i]->TurnCard(facedown);
|
||||
temp[pos] = m_cards[i];
|
||||
m_cards[i] = 0;
|
||||
}
|
||||
|
||||
// Copy each card back into the m_pack in a random
|
||||
// position. If position is occupied then find nearest
|
||||
// unoccupied position after the random position.
|
||||
for (i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
int pos = rand() % (m_topCard + 1);
|
||||
while (m_cards[pos])
|
||||
{
|
||||
pos++;
|
||||
if (pos > m_topCard) pos = 0;
|
||||
}
|
||||
m_cards[pos] = temp[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Pack::Redraw(wxDC& dc)
|
||||
{
|
||||
Pile::Redraw(dc);
|
||||
|
||||
char str[10];
|
||||
sprintf(str, "%d ", m_topCard + 1);
|
||||
|
||||
dc.SetTextBackground(FortyApp::BackgroundColour());
|
||||
dc.SetTextForeground(FortyApp::TextColour());
|
||||
dc.DrawText(str, m_x + CardWidth + 5, m_y + CardHeight / 2);
|
||||
|
||||
}
|
||||
|
||||
void Pack::AddCard(Card* card)
|
||||
{
|
||||
if (card == m_cards[m_topCard + 1])
|
||||
{
|
||||
m_topCard++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageBox("Pack::AddCard() Undo error", "Forty Thieves: Warning",
|
||||
wxOK | wxICON_EXCLAMATION);
|
||||
}
|
||||
card->TurnCard(facedown);
|
||||
}
|
||||
|
||||
|
||||
Pack::~Pack()
|
||||
{
|
||||
for (m_topCard = 0; m_topCard < NumCards; m_topCard++)
|
||||
{
|
||||
delete m_cards[m_topCard];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------//
|
||||
// The Base class: holds the initial pile of four cards //
|
||||
//------------------------------------------------------//
|
||||
Base::Base(int x, int y) : Pile(x, y, 0, 12)
|
||||
{
|
||||
m_topCard = -1;
|
||||
}
|
||||
|
||||
|
||||
bool Base::AcceptCard(Card* card)
|
||||
{
|
||||
bool retval = FALSE;
|
||||
|
||||
if (m_topCard >= 0)
|
||||
{
|
||||
if (m_cards[m_topCard]->GetSuit() == card->GetSuit() &&
|
||||
m_cards[m_topCard]->GetPipValue() - 1 == card->GetPipValue())
|
||||
{
|
||||
retval = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pile is empty - ACCEPT
|
||||
retval = TRUE;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Base::~Base()
|
||||
{
|
||||
// nothing special at the moment
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
// The Foundation class: holds the cards built up from the ace... //
|
||||
//----------------------------------------------------------------//
|
||||
Foundation::Foundation(int x, int y) : Pile(x, y, 0, 0)
|
||||
{
|
||||
m_topCard = -1;
|
||||
}
|
||||
|
||||
bool Foundation::AcceptCard(Card* card)
|
||||
{
|
||||
bool retval = FALSE;
|
||||
|
||||
if (m_topCard >= 0)
|
||||
{
|
||||
if (m_cards[m_topCard]->GetSuit() == card->GetSuit() &&
|
||||
m_cards[m_topCard]->GetPipValue() + 1 == card->GetPipValue())
|
||||
{
|
||||
retval = TRUE;
|
||||
}
|
||||
}
|
||||
else if (card->GetPipValue() == 1)
|
||||
{
|
||||
// It's an ace and the pile is empty - ACCEPT
|
||||
retval = TRUE;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Foundation::~Foundation()
|
||||
{
|
||||
// nothing special at the moment
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------//
|
||||
// The Discard class: holds cards dealt from the m_pack //
|
||||
//----------------------------------------------------//
|
||||
Discard::Discard(int x, int y) : Pile(x, y, 19, 0)
|
||||
{
|
||||
m_topCard = -1;
|
||||
}
|
||||
|
||||
void Discard::Redraw(wxDC& dc)
|
||||
{
|
||||
if (m_topCard >= 0)
|
||||
{
|
||||
if (m_dx == 0 && m_dy == 0)
|
||||
{
|
||||
m_cards[m_topCard]->Draw(dc, m_x, m_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = m_x;
|
||||
int y = m_y;
|
||||
for (int i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
m_cards[i]->Draw(dc, x, y);
|
||||
x += m_dx;
|
||||
y += m_dy;
|
||||
if (i == 31)
|
||||
{
|
||||
x = m_x;
|
||||
y = m_y + CardHeight / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Card::DrawNullCard(dc, m_x, m_y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Discard::GetTopCardPos(int& x, int& y)
|
||||
{
|
||||
if (m_topCard < 0)
|
||||
{
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
}
|
||||
else if (m_topCard > 31)
|
||||
{
|
||||
x = m_x + m_dx * (m_topCard - 32);
|
||||
y = m_y + CardHeight / 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = m_x + m_dx * m_topCard;
|
||||
y = m_y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Card* Discard::RemoveTopCard(wxDC& dc, int m_xOffset, int m_yOffset)
|
||||
{
|
||||
Card* card;
|
||||
|
||||
if (m_topCard <= 31)
|
||||
{
|
||||
card = Pile::RemoveTopCard(dc, m_xOffset, m_yOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
int topX, topY, x, y;
|
||||
GetTopCardPos(topX, topY);
|
||||
card = Pile::RemoveTopCard();
|
||||
card->Erase(dc, topX - m_xOffset, topY - m_yOffset);
|
||||
GetTopCardPos(x, y);
|
||||
dc.SetClippingRegion(topX - m_xOffset, topY - m_yOffset,
|
||||
CardWidth, CardHeight);
|
||||
|
||||
for (int i = m_topCard - 31; i <= m_topCard - 31 + CardWidth / m_dx; i++)
|
||||
{
|
||||
m_cards[i]->Draw(dc, m_x - m_xOffset + i * m_dx, m_y - m_yOffset);
|
||||
}
|
||||
if (m_topCard > 31)
|
||||
{
|
||||
m_cards[m_topCard]->Draw(dc, topX - m_xOffset - m_dx, topY - m_yOffset);
|
||||
}
|
||||
dc.DestroyClippingRegion();
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
Discard::~Discard()
|
||||
{
|
||||
// nothing special at the moment
|
||||
};
|
135
demos/forty/game.h
Normal file
135
demos/forty/game.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: game.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _GAME_H_
|
||||
#define _GAME_H_
|
||||
#include "card.h"
|
||||
#include "pile.h"
|
||||
|
||||
const int MaxMoves = 800;
|
||||
|
||||
|
||||
//---------------------------------------//
|
||||
// A class which holds the pack of cards //
|
||||
//---------------------------------------//
|
||||
class Pack : public Pile {
|
||||
public:
|
||||
Pack(int x, int y);
|
||||
~Pack();
|
||||
void Redraw(wxDC& dc);
|
||||
void ResetPile() { m_topCard = NumCards - 1; }
|
||||
void Shuffle();
|
||||
void AddCard(Card* card); // Add card
|
||||
void AddCard(wxDC& dc, Card* card) { AddCard(card); Redraw(dc); }
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------//
|
||||
// A class which holds a base i.e. the initial 10 x 4 cards //
|
||||
//----------------------------------------------------------//
|
||||
class Base : public Pile {
|
||||
public:
|
||||
Base(int x, int y);
|
||||
~Base();
|
||||
bool AcceptCard(Card* card);
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------//
|
||||
// A class which holds a foundation i.e. Ace, 2, 3... //
|
||||
//----------------------------------------------------//
|
||||
class Foundation : public Pile {
|
||||
public:
|
||||
Foundation(int x, int y);
|
||||
~Foundation();
|
||||
bool AcceptCard(Card* card);
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------//
|
||||
// A class which holds the discard pile //
|
||||
//--------------------------------------//
|
||||
class Discard : public Pile {
|
||||
public:
|
||||
Discard(int x, int y);
|
||||
~Discard();
|
||||
void Redraw(wxDC& dc);
|
||||
void GetTopCardPos(int& x, int& y);
|
||||
Card* RemoveTopCard(wxDC& dc, int m_xOffset, int m_yOffset);
|
||||
};
|
||||
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game(int wins, int games, int score);
|
||||
virtual ~Game();
|
||||
|
||||
void NewPlayer(int wins, int games, int score);
|
||||
void Deal(); // Shuffle and deal a new game
|
||||
bool CanYouGo(int x, int y); // can card under (x,y) go somewhere?
|
||||
bool HaveYouWon(); // have you won the game?
|
||||
|
||||
void Undo(wxDC& dc); // Undo the last go
|
||||
void Redo(wxDC& dc); // Redo the last go
|
||||
|
||||
void Redraw(wxDC& dc);
|
||||
void DisplayScore(wxDC& dc);
|
||||
bool LButtonDown(wxDC& dc, int mx, int my); //
|
||||
void LButtonUp(wxDC& dc, int mx, int my);
|
||||
void LButtonDblClk(wxDC& dc, int mx, int my);
|
||||
void MouseMove(wxDC& dc, int mx, int my);
|
||||
|
||||
int GetNumWins() const { return m_numWins; }
|
||||
int GetNumGames() const { return m_numGames; }
|
||||
int GetScore() const { return m_currentScore + m_totalScore; }
|
||||
|
||||
bool InPlay() const { return m_inPlay; }
|
||||
|
||||
private:
|
||||
bool DropCard(int x, int y, Pile* pile, Card* card);
|
||||
// can the card at (x, y) be dropped on the pile?
|
||||
Pile* WhichPile(int x, int y); // which pile is (x, y) over?
|
||||
void DoMove(wxDC& dc, Pile* src, Pile* dest);
|
||||
|
||||
bool m_inPlay; // flag indicating that the game has started
|
||||
|
||||
// undo buffer
|
||||
struct {
|
||||
Pile* src;
|
||||
Pile* dest;
|
||||
} m_moves[MaxMoves];
|
||||
int m_moveIndex; // current position in undo/redo buffer
|
||||
int m_redoIndex; // max move index available for redo
|
||||
|
||||
// the various piles of cards
|
||||
Pack* m_pack;
|
||||
Discard* m_discard;
|
||||
Base* m_bases[10];
|
||||
Foundation* m_foundations[8];
|
||||
|
||||
// variables to do with dragging cards
|
||||
Pile* m_srcPile;
|
||||
Card* m_liftedCard;
|
||||
int m_xPos, m_yPos; // current coords of card being dragged
|
||||
int m_xOffset, m_yOffset; // card/mouse offset when dragging a card
|
||||
|
||||
wxBitmap* m_bmap;
|
||||
wxBitmap* m_bmapCard;
|
||||
|
||||
// variables to do with scoring
|
||||
int m_numGames;
|
||||
int m_numWins;
|
||||
int m_totalScore;
|
||||
int m_currentScore;
|
||||
};
|
||||
|
||||
#endif // _GAME_H_
|
BIN
demos/forty/make_cw.mcp
Normal file
BIN
demos/forty/make_cw.mcp
Normal file
Binary file not shown.
16
demos/forty/makefile.b32
Normal file
16
demos/forty/makefile.b32
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# File: makefile.b32
|
||||
# Author: Julian Smart
|
||||
# Created: 1999
|
||||
# Updated:
|
||||
# Copyright:
|
||||
#
|
||||
# Makefile : Builds sample for 32-bit BC++
|
||||
|
||||
WXDIR = $(WXWIN)
|
||||
|
||||
TARGET=forty
|
||||
OBJECTS = $(TARGET).obj canvas.obj card.obj game.obj pile.obj playerdg.obj scoredg.obj scorefil.obj
|
||||
|
||||
!include $(WXDIR)\src\makeprog.b32
|
||||
|
19
demos/forty/makefile.bcc
Normal file
19
demos/forty/makefile.bcc
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# File: makefile.bcc
|
||||
# Author: Julian Smart
|
||||
# Created: 1998
|
||||
# Updated:
|
||||
#
|
||||
# Builds a BC++ 16-bit sample
|
||||
|
||||
!if "$(WXWIN)" == ""
|
||||
!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
|
||||
!endif
|
||||
|
||||
WXDIR = $(WXWIN)
|
||||
|
||||
TARGET=forty
|
||||
OBJECTS=$(TARGET).obj canvas.obj card.obj game.obj pile.obj playerdg.obj scoredg.obj scorefil.obj
|
||||
|
||||
!include $(WXDIR)\src\makeprog.bcc
|
||||
|
17
demos/forty/makefile.dos
Normal file
17
demos/forty/makefile.dos
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# File: makefile.dos
|
||||
# Author: Julian Smart
|
||||
# Created: 1998
|
||||
# Updated:
|
||||
#
|
||||
# Makefile : Builds 16-bit sample, VC++ 1.5
|
||||
# Use FINAL=1 argument to nmake to build final version with no debugging
|
||||
# info
|
||||
|
||||
WXDIR = $(WXWIN)
|
||||
|
||||
TARGET=forty
|
||||
OBJECTS = $(TARGET).obj canvas.obj card.obj game.obj pile.obj playerdg.obj scoredg.obj scorefil.obj
|
||||
|
||||
!include $(WXDIR)\src\makeprog.msc
|
||||
|
16
demos/forty/makefile.g95
Normal file
16
demos/forty/makefile.g95
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# File: makefile.g95
|
||||
# Author: Julian Smart
|
||||
# Created: 1999
|
||||
# Updated:
|
||||
# Copyright: (c) Julian Smart, 1999
|
||||
#
|
||||
# Makefile for wxWindows sample (Cygwin/Mingw32).
|
||||
|
||||
WXDIR = ../..
|
||||
|
||||
TARGET=forty
|
||||
OBJECTS = $(TARGET).o canvas.o card.o game.o pile.o playerdg.o scoredg.o scorefil.o
|
||||
|
||||
include $(WXDIR)/src/makeprog.g95
|
||||
|
35
demos/forty/makefile.unx
Normal file
35
demos/forty/makefile.unx
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# File: Makefile for samples
|
||||
# Author: Robert Roebling
|
||||
# Created: 1999
|
||||
# Updated:
|
||||
# Copyright: (c) 1998 Robert Roebling
|
||||
#
|
||||
# This makefile requires a Unix version of wxWindows
|
||||
# to be installed on your system. This is most often
|
||||
# done typing "make install" when using the complete
|
||||
# sources of wxWindows or by installing the two
|
||||
# RPM packages wxGTK.XXX.rpm and wxGTK-devel.XXX.rpm
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
CC = g++
|
||||
|
||||
PROGRAM = forty
|
||||
|
||||
OBJECTS = $(PROGRAM).o canvas.o card.o game.o pile.o playerdg.o scoredg.o scorefil.o
|
||||
|
||||
# implementation
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
.cpp.o :
|
||||
$(CC) -c `wx-config --cflags` -o $@ $<
|
||||
|
||||
all: $(PROGRAM)
|
||||
|
||||
$(PROGRAM): $(OBJECTS)
|
||||
$(CC) -o $(PROGRAM) $(OBJECTS) `wx-config --libs`
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROGRAM)
|
18
demos/forty/makefile.vc
Normal file
18
demos/forty/makefile.vc
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# File: makefile.vc
|
||||
# Author: Julian Smart
|
||||
# Created: 1999
|
||||
# Updated:
|
||||
# Copyright: (c) Julian Smart
|
||||
#
|
||||
# Makefile : Builds sample (VC++, WIN32)
|
||||
# Use FINAL=1 argument to nmake to build final version with no debug info.
|
||||
|
||||
# Set WXDIR for your system
|
||||
WXDIR = $(WXWIN)
|
||||
|
||||
PROGRAM=forty
|
||||
OBJECTS = $(PROGRAM).obj card.obj canvas.obj game.obj pile.obj playerdg.obj scoredg.obj scorefil.obj
|
||||
|
||||
!include $(WXDIR)\src\makeprog.vc
|
||||
|
15
demos/forty/makefile.wat
Normal file
15
demos/forty/makefile.wat
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Makefile for WATCOM
|
||||
#
|
||||
# Created by Julian Smart, January 1999
|
||||
#
|
||||
#
|
||||
|
||||
WXDIR = $(%WXWIN)
|
||||
|
||||
PROGRAM = forty
|
||||
OBJECTS = $(PROGRAM).obj canvas.obj card.obj game.obj pile.obj playerdg.obj scoredg.obj scorefil.obj
|
||||
|
||||
!include $(WXDIR)\src\makeprog.wat
|
||||
|
||||
|
BIN
demos/forty/pictures.bmp
Normal file
BIN
demos/forty/pictures.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
60
demos/forty/pictures.xpm
Normal file
60
demos/forty/pictures.xpm
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XPM */
|
||||
static char *Pictures[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 120 45 8 1",
|
||||
/* colors */
|
||||
". c #000000",
|
||||
"# c #c0c0c0",
|
||||
"a c #808080",
|
||||
"b c #ff0000",
|
||||
"c c #ffff00",
|
||||
"d c #0000ff",
|
||||
"e c #00ffff",
|
||||
"f c #ffffff",
|
||||
/* pixels */
|
||||
"........................................................................................................................",
|
||||
".fff.fffffff.bb.bb.bb.b.fffffffffffffff..fffffffffff..f..bbc.cc..ffffffffffffff..fff.ffffff.bbccccbcccccbb.ffffffffffff.",
|
||||
".ff.c.fffffff.bbbbbbbb.ffffffffffffffff..fff.ffffff..f.ff.bbc..c.ffffffffffffff..ff.a.ffffff.bbccbbbcccbb.fffffffffffff.",
|
||||
".f.cbc.fffffff........fffffffffffffffff..ff.b.fffff.f.ffff.bb..c..fffffffffffff..f.#af.ffffff.bbbbbbbbbb.ffffffffffffff.",
|
||||
".f.cbc.ffffff.fff.c.c.fffffffffffffffff..ff.b.fffff..f.ff.f.bbc.c.fffffffffffff..f.#af.ffffff............ffffffffffffff.",
|
||||
".ff.c.fffffff.f..f.c.c.ffffffffffffffff..fff.ffffff.f..ff..f.bb..ffffffffffffff..f.#af.ffffff.a..f.fff.f.ffffffffffffff.",
|
||||
".f.cbc.ffffff.f.ff.c.c.ffffffffffffffff..ff.c.fffff.fff.ffff..b.fffffffffffffff..f.#af.ffffff.a.f..fff..f.fffffffffffff.",
|
||||
".f.cbc.fffff.fffff.c.c.ffffffffffffffff..ff.c.fffff.fff.ffff....fffffffffffffff..f.#af.ffffff.a.ffff.ffff.fffffffffffff.",
|
||||
".ff.c.fffff.ffffff.c.c.ffffffffffffffff..ff.c.fffff.fff..fff.b..fffffffffffffff..f.#af.ffffff.a.fffff.fff.fffffffffffff.",
|
||||
".f.cbc.ffff..###ff.c.c.ffffffffffffffff..ff.c.fffff.ffffffff..b.fffffffffffffff..f.#af.ffffff.a.ffff..fff.fffffffffffff.",
|
||||
".f.cbc.ffffff...ff.c.c.ffffffffffffffff..fff.ffffff.ffbbbbff.f...ffffffffffffff..f.#af.fff..f.a..ffffffff.fffffffffffff.",
|
||||
".ff....ffffff.ffff.c.c.ffffffffffffffff..ff....fffff.ffffff.f.f...fffffffffffff..f.#af.fff....a...f....f..fffffffffffff.",
|
||||
".f.ffff.fffff.fffff.c.c.fffffffffffffff..f.ffff.ffff..ffff.f.f.f..fffffffffffff..f.#af.ffff.aaa.a..f.f.f...ffffffffffff.",
|
||||
".f....ff.f.................ffffffffffff..f....ff.f.................ffffffffffff..f.#af.fff...................ffffffffff.",
|
||||
".ff.fff....eddddddddddddddd.....fffffff..f.fffff...ffffffffff.cdbb......fffffff..f.#af.....c.cc..bbbbbb..c......fffffff.",
|
||||
".ff....bbbd.dbcbbbbbbbbbcbdedbbb....fff..f....f.bc.fdddddddf.cdbb.d..f.....ffff..f.#af..cbbcc.cc..bbbb..c......b....fff.",
|
||||
"...bbbb...deedbbcbbcbbcbbbd.dbb.bbbb.....f.fff.fbbc.fffffff.cdbb.d..f..dd.c..ff..........cbbcc.cc......c.....bbbdfff....",
|
||||
".bb....c.ccdeedbbbcccbbbbdedbb.bbb..cc...ff...c.fbbc.fdddf.cdbb.d..f..dd.cccd.f...ffff...dcbbcc.cc....cc...ddbbbdfddddf.",
|
||||
"...cc.c....bd.dbcbbcbbcbbd.db.bb..cbc.b..ff.dccc.bbc.ffff.cdbb.dd..ff...cdcdfd.........f.dcbbacc.cccccc..fdcbdbbdffddff.",
|
||||
"..c....bbbbbdeddddddddddddedbb..cccc.bb..f..fdcdc.bbc.ff.cdbb.dddd..ff.cccdffdc...ffff.f.dcbbcacc.c...c.fdccccdbdffddff.",
|
||||
"...bb.bb....bbbbbbbbbbbbbbbb..ccbbc.bb....ffdfdccc.bbc..cdbb..........cccdfdfbc........f.dcbbccacc.ccb.fdddbdbdbddffffd.",
|
||||
".bbb.b..ccc.d.d.d.d.dd.d.d.d.cccbb.bb.b..cbdfffdccc.fdfdfdfdfdfdfdfd.cccdfffbbc...ffff.f.dcbbacca.bcdcc.caddddcddff..ff.",
|
||||
".bb.bb.ccbcd.d.d.d.ff.d.d.d.dcbcc.bb.bb..cbbddddcdc.dbdbdbdbdbdbdbdb.cdcddddbbc.........ddcddaacc.cdddc.ccaddcdd........",
|
||||
".b.bb.bbccc.d.d.d.dd.d.d.d.d.ccc.bb.bbb..cbbfffdccc.fdfdfdfdfdfdfdfd.cccdfffdbc..ff..ffddcddddaac.ccdcb.accbbcd.f.ffff..",
|
||||
"..bb.cbbcc..bbbbbbbbbbbbbbbb....b..bb....cbfdfdccc..........bbdc..cbb.cccdfdff...dffffddcdbdbddaac.bcc.ccacbbcd.f.......",
|
||||
".bb.cccc..bbdeddddddddddddedbbbbb....c...cdffdccc.ff..dddd.bbdc.ff.cbb.cdcdff.f..ffddffdbdccccdfa.c...c.ccabbcd.f.ffff..",
|
||||
".b.cbc..bb.bd.dbbcbbcbbcbd.db....c.cc.....dfdcdc...ff..dd.bbdc.ffff.cbb.cccd.ff..ffddffdbbdbcdff..cccccc.ccbbcd.f.......",
|
||||
"..cc..bbb.bbdedbbbbcccbbbdeedcc.c....bb..f.dccc.dd..f..d.bbdc.fdddf.cbbf.c...ff..fddddfdbbbddf...cc....cc.cbbcd...ffff..",
|
||||
"....bbbb.bbd.dbbbcbbcbbcbbdeed...bbbb....ff..c.dd..f..d.bbdc.fffffff.cbbf.fff.f.....fffdbbb......c......cc.cbbc.........",
|
||||
".fff....bbbdedbcbbbbbbbbbcbd.dbbb....ff..ffff.....f..d.bbdc.fdddddddf.cb.f....f..fff....bb......c..bbbb..cc.cbbc..fa#.f.",
|
||||
".fffffff.....ddddddddddddddde....fff.ff..fffffff......bbdc.ffffffffff...fffff.f..fffffff.......c..bbbbbb..cc......fa#.f.",
|
||||
".ffffffffffff.................f.ff....f..ffffffffffff.................f.ff....f..ffffffffff...................fff.fa#.f.",
|
||||
".fffffffffffffff.c.c.fffff.fffff.ffff.f..fffffffffffff..f.f.f.ffff..ffff.ffff.f..ffffffffffff...f.f.f..a.aaa.ffff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.ffff.ffffff....ff..fffffffffffff...f.f.ffffff.fffff....ff..fffffffffffff..f....f...a....fff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.ff...ffffff.cbc.f..ffffffffffffff...f.ffbbbbff.ffffff.fff..fffffffffffff.ffffffff..a.f..fff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.ff###..ffff.cbc.f..fffffffffffffff.b..ffffffff.fffff.c.ff..fffffffffffff.fff..ffff.a.ffffff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.ffffff.fffff.c.ff..fffffffffffffff..b.fff..fff.fffff.c.ff..fffffffffffff.fff.fffff.a.ffffff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.fffff.fffff.cbc.f..fffffffffffffff....ffff.fff.fffff.c.ff..fffffffffffff.ffff.ffff.a.ffffff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.ff.f.ffffff.cbc.f..fffffffffffffff.b..ffff.fff.fffff.c.ff..fffffffffffff.f..fff..f.a.ffffff.fa#.f.",
|
||||
".ffffffffffffffff.c.c.f..f.fffffff.c.ff..ffffffffffffff..bb.f..ff..f.ffffff.fff..ffffffffffffff.f.fff.ff.a.ffffff.fa#.f.",
|
||||
".fffffffffffffffff.c.c.fff.ffffff.cbc.f..fffffffffffff.c.cbb.f.ff.f..fffff.b.ff..ffffffffffffff............ffffff.fa#.f.",
|
||||
".fffffffffffffffff........fffffff.cbc.f..fffffffffffff..c..bb.ffff.f.fffff.b.ff..ffffffffffffff.bbbbbbbbbb.ffffff.fa#.f.",
|
||||
".ffffffffffffffff.bbbbbbbb.fffffff.c.ff..ffffffffffffff.c..cbb.ff.f..ffffff.fff..fffffffffffff.bbcccbbbccbb.ffffff.a.ff.",
|
||||
".fffffffffffffff.b.bb.bb.bb.fffffff.fff..ffffffffffffff..cc.cbb..f..fffffffffff..ffffffffffff.bbcccccbccccbb.ffffff.fff.",
|
||||
"........................................................................................................................"
|
||||
};
|
305
demos/forty/pile.cpp
Normal file
305
demos/forty/pile.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: pile.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| The base class for holding piles of playing cards. |
|
||||
//+-------------------------------------------------------------+
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "card.h"
|
||||
#include "pile.h"
|
||||
|
||||
#include "wx/app.h"
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Pile::Pile() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Initialise the pile to be empty of cards. |
|
||||
//+-------------------------------------------------------------+
|
||||
Pile::Pile(int x, int y, int dx, int dy)
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_dx = dx;
|
||||
m_dy = dy;
|
||||
for (m_topCard = 0; m_topCard < NumCards; m_topCard++)
|
||||
{
|
||||
m_cards[m_topCard] = 0;
|
||||
}
|
||||
m_topCard = -1; // i.e. empty
|
||||
}
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Pile::Redraw() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Redraw the pile on the screen. If the pile is empty |
|
||||
//| just draw a NULL card as a place holder for the pile. |
|
||||
//| Otherwise draw the pile from the bottom up, starting |
|
||||
//| at the origin of the pile, shifting each subsequent |
|
||||
//| card by the pile's x and y offsets. |
|
||||
//+-------------------------------------------------------------+
|
||||
void Pile::Redraw(wxDC& dc )
|
||||
{
|
||||
wxWindow *frame = wxTheApp->GetTopWindow();
|
||||
wxWindow *canvas = (wxWindow *) NULL;
|
||||
if (frame)
|
||||
{
|
||||
wxNode *node = frame->GetChildren().First();
|
||||
if (node) canvas = (wxWindow*)node->Data();
|
||||
}
|
||||
|
||||
if (m_topCard >= 0)
|
||||
{
|
||||
if (m_dx == 0 && m_dy == 0)
|
||||
{
|
||||
if ((canvas) && (canvas->IsExposed(m_x,m_y,60,200)))
|
||||
m_cards[m_topCard]->Draw(dc, m_x, m_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x = m_x;
|
||||
int y = m_y;
|
||||
for (int i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
if ((canvas) && (canvas->IsExposed(x,y,60,200)))
|
||||
m_cards[i]->Draw(dc, x, y);
|
||||
x += m_dx;
|
||||
y += m_dy;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((canvas) && (canvas->IsExposed(m_x,m_y,60,200)))
|
||||
Card::DrawNullCard(dc, m_x, m_y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Pile::GetTopCard() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| Return a pointer to the top card in the pile or NULL |
|
||||
//| if the pile is empty. |
|
||||
//| NB: Gets a copy of the card without removing it from the |
|
||||
//| pile. |
|
||||
//+-------------------------------------------------------------+
|
||||
Card* Pile::GetTopCard()
|
||||
{
|
||||
Card* card = 0;
|
||||
|
||||
if (m_topCard >= 0)
|
||||
{
|
||||
card = m_cards[m_topCard];
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Pile::RemoveTopCard() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| If the pile is not empty, remove the top card from the |
|
||||
//| pile and return the pointer to the removed card. |
|
||||
//| If the pile is empty return a NULL pointer. |
|
||||
//+-------------------------------------------------------------+
|
||||
Card* Pile::RemoveTopCard()
|
||||
{
|
||||
Card* card = 0;
|
||||
|
||||
if (m_topCard >= 0)
|
||||
{
|
||||
card = m_cards[m_topCard--];
|
||||
}
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
//+-------------------------------------------------------------+
|
||||
//| Pile::RemoveTopCard() |
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| As RemoveTopCard() but also redraw the top of the pile |
|
||||
//| after the card has been removed. |
|
||||
//| NB: the offset allows for the redrawn area to be in a |
|
||||
//| bitmap ready for 'dragging' cards acrosss the screen. |
|
||||
//+-------------------------------------------------------------+
|
||||
Card* Pile::RemoveTopCard(wxDC& dc, int xOffset, int yOffset)
|
||||
{
|
||||
int topX, topY, x, y;
|
||||
|
||||
GetTopCardPos(topX, topY);
|
||||
Card* card = RemoveTopCard();
|
||||
|
||||
if (card)
|
||||
{
|
||||
card->Erase(dc, topX - xOffset, topY - yOffset);
|
||||
GetTopCardPos(x, y);
|
||||
if (m_topCard < 0)
|
||||
{
|
||||
Card::DrawNullCard(dc, x - xOffset, y - yOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cards[m_topCard]->Draw(dc, x - xOffset, y - yOffset);
|
||||
}
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
|
||||
void Pile::GetTopCardPos(int& x, int& y)
|
||||
{
|
||||
if (m_topCard < 0)
|
||||
{
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = m_x + m_dx * m_topCard;
|
||||
y = m_y + m_dy * m_topCard;
|
||||
}
|
||||
}
|
||||
|
||||
void Pile::AddCard(Card* card)
|
||||
{
|
||||
if (m_topCard < -1) m_topCard = -1;
|
||||
|
||||
m_cards[++m_topCard] = card;
|
||||
}
|
||||
|
||||
void Pile::AddCard(wxDC& dc, Card* card)
|
||||
{
|
||||
AddCard(card);
|
||||
int x, y;
|
||||
GetTopCardPos(x, y);
|
||||
card->Draw(dc, x, y);
|
||||
}
|
||||
|
||||
// Can the card leave this pile.
|
||||
// If it is a member of the pile then the answer is yes.
|
||||
// Derived classes may override this behaviour to incorporate
|
||||
// the rules of the game
|
||||
bool Pile::CanCardLeave(Card* card)
|
||||
{
|
||||
for (int i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
if (card == m_cards[i]) return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Calculate how far x, y is from top card in the pile
|
||||
// Returns the square of the distance
|
||||
int Pile::CalcDistance(int x, int y)
|
||||
{
|
||||
int cx, cy;
|
||||
GetTopCardPos(cx, cy);
|
||||
return ((cx - x) * (cx - x) + (cy - y) * (cy - y));
|
||||
}
|
||||
|
||||
|
||||
// Return the card at x, y. Check the top card first, then
|
||||
// work down the pile. If a card is found then return a pointer
|
||||
// to the card, otherwise return NULL
|
||||
Card* Pile::GetCard(int x, int y)
|
||||
{
|
||||
int cardX;
|
||||
int cardY;
|
||||
GetTopCardPos(cardX, cardY);
|
||||
|
||||
for (int i = m_topCard; i >= 0; i--)
|
||||
{
|
||||
if (x >= cardX && x <= cardX + CardWidth &&
|
||||
y >= cardY && y <= cardY + CardHeight)
|
||||
{
|
||||
return m_cards[i];
|
||||
}
|
||||
cardX -= m_dx;
|
||||
cardY -= m_dy;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Return the position of the given card. If it is not a member of this pile
|
||||
// return the origin of the pile.
|
||||
void Pile::GetCardPos(Card* card, int& x, int& y)
|
||||
{
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
|
||||
for (int i = 0; i <= m_topCard; i++)
|
||||
{
|
||||
if (card == m_cards[i])
|
||||
{
|
||||
return;
|
||||
}
|
||||
x += m_dx;
|
||||
y += m_dy;
|
||||
}
|
||||
|
||||
// card not found in pile, return origin of pile
|
||||
x = m_x;
|
||||
y = m_y;
|
||||
}
|
||||
|
||||
|
||||
bool Pile::Overlap(int x, int y)
|
||||
{
|
||||
int cardX;
|
||||
int cardY;
|
||||
GetTopCardPos(cardX, cardY);
|
||||
|
||||
if (x >= cardX - CardWidth && x <= cardX + CardWidth &&
|
||||
y >= cardY - CardHeight && y <= cardY + CardHeight)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
Pile::~Pile()
|
||||
{
|
||||
// nothing special at the moment
|
||||
}
|
80
demos/forty/pile.h
Normal file
80
demos/forty/pile.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: pile.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//+-------------------------------------------------------------+
|
||||
//| Description: |
|
||||
//| The base class for holding piles of playing cards. |
|
||||
//| This is the basic building block for card games. A pile |
|
||||
//| has a position on the screen and an offset for each |
|
||||
//| card placed on it e.g. a pack has no offset, but the |
|
||||
//| discard pile may be fanned out across the screen. |
|
||||
//| |
|
||||
//| The pile knows how to draw itself, though this may be |
|
||||
//| overridden if the default layout needs to be changed. |
|
||||
//| One or more cards can be removed from the top of a pile, |
|
||||
//| and single cards can be added to the top of a pile. |
|
||||
//| Functions are provided which redraw the screen when |
|
||||
//| cards are added or removed. |
|
||||
//| |
|
||||
//| Cards know which way up they are and how to draw |
|
||||
//| themselves. Piles are lists of cards. Piles know which |
|
||||
//| cards they contain and where they are to be drawn. |
|
||||
//+-------------------------------------------------------------+
|
||||
#ifndef _PILE_H_
|
||||
#define _PILE_H_
|
||||
#include "card.h"
|
||||
|
||||
const int NumCards = 2 * PackSize;
|
||||
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
// A class defining a pile of cards with a position on the screen //
|
||||
//----------------------------------------------------------------//
|
||||
class Pile {
|
||||
public:
|
||||
Pile(int x, int y, int dx = 0, int dy = 0);
|
||||
virtual ~Pile();
|
||||
|
||||
// General functions
|
||||
virtual void ResetPile() { m_topCard = -1; }
|
||||
virtual void Redraw(wxDC& pDC);
|
||||
|
||||
// Card query functions
|
||||
virtual Card* GetCard(int x, int y); // Get pointer to card at x, y
|
||||
Card* GetTopCard(); // Get pointer to top card
|
||||
virtual void GetCardPos(Card* card, int& x, int& y);
|
||||
// Get position of a card
|
||||
virtual void GetTopCardPos(int& x, int& y);
|
||||
// Get position of the top card
|
||||
int GetNumCards() { return m_topCard + 1; } // Number of cards in pile
|
||||
bool Overlap(int x, int y); // does card at x,y overlap the pile?
|
||||
int CalcDistance(int x, int y); // calculates the square of the distance
|
||||
// of a card at (x,y) from the top of the pile
|
||||
|
||||
// Functions removing one or more cards from the top of a pile
|
||||
virtual bool CanCardLeave(Card* card);
|
||||
Card* RemoveTopCard();
|
||||
virtual Card* RemoveTopCard(wxDC& pDC, int xOffset = 0, int yOffset = 0);
|
||||
|
||||
// Functions to add a card to the top of a pile
|
||||
virtual bool AcceptCard(Card*) { return FALSE; }
|
||||
virtual void AddCard(Card* card); // Add card to top of pile
|
||||
virtual void AddCard(wxDC& pDC, Card* card); // Add card + redraw it
|
||||
|
||||
protected:
|
||||
int m_x, m_y; // Position of the pile on the screen
|
||||
int m_dx, m_dy; // Offset when drawing the pile
|
||||
Card* m_cards[NumCards]; // Array of cards in this pile
|
||||
int m_topCard; // Array index of the top card
|
||||
};
|
||||
|
||||
#endif // _PILE_H_
|
188
demos/forty/playerdg.cpp
Normal file
188
demos/forty/playerdg.cpp
Normal file
@@ -0,0 +1,188 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: playerdg.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#include "scorefil.h"
|
||||
#include "playerdg.h"
|
||||
|
||||
const int ID_LISTBOX = 101;
|
||||
|
||||
BEGIN_EVENT_TABLE(PlayerSelectionDialog, wxDialog)
|
||||
EVT_SIZE(PlayerSelectionDialog::OnSize)
|
||||
EVT_BUTTON(wxID_OK, PlayerSelectionDialog::ButtonCallback)
|
||||
EVT_BUTTON(wxID_CANCEL, PlayerSelectionDialog::ButtonCallback)
|
||||
EVT_LISTBOX(ID_LISTBOX, PlayerSelectionDialog::SelectCallback)
|
||||
EVT_CLOSE(PlayerSelectionDialog::OnCloseWindow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
PlayerSelectionDialog::PlayerSelectionDialog(
|
||||
wxWindow* parent,
|
||||
ScoreFile* file
|
||||
) :
|
||||
wxDialog(parent, -1, "Player Selection",
|
||||
wxDefaultPosition, wxSize(320, 200),
|
||||
wxDIALOG_MODAL | wxDEFAULT_DIALOG_STYLE),
|
||||
m_scoreFile(file)
|
||||
{
|
||||
// enable constraints
|
||||
SetAutoLayout (TRUE);
|
||||
|
||||
wxStaticText* msg = new wxStaticText(this, -1, "Please select a name from the list");
|
||||
|
||||
wxListBox* list = new wxListBox(
|
||||
this, ID_LISTBOX,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
0, 0,
|
||||
wxLB_SINGLE
|
||||
);
|
||||
|
||||
wxArrayString players;
|
||||
m_scoreFile->GetPlayerList(players);
|
||||
for (unsigned int i = 0; i < players.Count(); i++)
|
||||
{
|
||||
list->Append(players[i]);
|
||||
}
|
||||
|
||||
m_textField = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_OK = new wxButton(this, wxID_OK, "OK");
|
||||
m_cancel = new wxButton(this, wxID_CANCEL, "Cancel");
|
||||
|
||||
wxLayoutConstraints* layout;
|
||||
|
||||
// Constrain the msg at the top of the window
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.SameAs (this, wxLeft, 10);
|
||||
layout->top.SameAs (this, wxTop, 10);
|
||||
layout->height.AsIs();
|
||||
layout->width.AsIs();
|
||||
msg->SetConstraints(layout);
|
||||
|
||||
// Constrain the OK button
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.SameAs (this, wxLeft, 10);
|
||||
layout->bottom.SameAs (this, wxBottom, 10);
|
||||
layout->height.AsIs();
|
||||
layout->width.AsIs();
|
||||
m_OK->SetConstraints(layout);
|
||||
|
||||
// Constrain the OK button
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.RightOf (m_OK, 10);
|
||||
layout->bottom.SameAs (this, wxBottom, 10);
|
||||
layout->height.AsIs();
|
||||
layout->width.AsIs();
|
||||
m_cancel->SetConstraints(layout);
|
||||
|
||||
// Constrain the Name text entry field
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.SameAs (this, wxLeft, 10);
|
||||
layout->right.SameAs (this, wxRight, 10);
|
||||
layout->bottom.SameAs (m_OK, wxTop, 10);
|
||||
layout->height.AsIs();
|
||||
m_textField->SetConstraints(layout);
|
||||
|
||||
// Constrain the list of players
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.SameAs (this, wxLeft, 10);
|
||||
layout->right.SameAs (this, wxRight, 10);
|
||||
layout->top.Below (msg, 10);
|
||||
layout->bottom.SameAs (m_textField, wxTop, 10);
|
||||
list->SetConstraints(layout);
|
||||
|
||||
wxString prevPlayer = m_scoreFile->GetPreviousPlayer();
|
||||
if (prevPlayer.Length() > 0)
|
||||
{
|
||||
list->SetStringSelection(prevPlayer);
|
||||
m_textField->SetValue(prevPlayer);
|
||||
}
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
PlayerSelectionDialog::~PlayerSelectionDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void PlayerSelectionDialog::OnSize(wxSizeEvent& WXUNUSED(event))
|
||||
{
|
||||
Layout();
|
||||
}
|
||||
|
||||
const wxString& PlayerSelectionDialog::GetPlayersName()
|
||||
{
|
||||
/*
|
||||
m_player = "";
|
||||
Show(TRUE);
|
||||
*/
|
||||
return m_player;
|
||||
}
|
||||
|
||||
void PlayerSelectionDialog::OnCloseWindow(wxCloseEvent& event)
|
||||
{
|
||||
m_player = "";
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
void PlayerSelectionDialog::SelectCallback(wxCommandEvent& event)
|
||||
{
|
||||
if (event.GetEventType() == wxEVT_COMMAND_LISTBOX_SELECTED)
|
||||
{
|
||||
// if (event.IsSelection())
|
||||
m_textField->SetValue(event.GetString());
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSelectionDialog::ButtonCallback(wxCommandEvent& event)
|
||||
{
|
||||
if (event.GetId() == wxID_OK)
|
||||
{
|
||||
wxString name = m_textField->GetValue();
|
||||
if (!name.IsNull() && name.Length() > 0)
|
||||
{
|
||||
if (name.Contains('@'))
|
||||
{
|
||||
wxMessageBox("Names should not contain the '@' character", "Forty Thieves");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player = name;
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageBox("Please enter your name", "Forty Thieves");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player = "";
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
}
|
41
demos/forty/playerdg.h
Normal file
41
demos/forty/playerdg.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: playerdg.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _PLAYERDG_H_
|
||||
#define _PLAYERDG_H_
|
||||
|
||||
class PlayerSelectionDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
PlayerSelectionDialog(wxWindow* parent, ScoreFile* file);
|
||||
virtual ~PlayerSelectionDialog();
|
||||
|
||||
const wxString& GetPlayersName();
|
||||
void ButtonCallback(wxCommandEvent& event);
|
||||
void SelectCallback(wxCommandEvent& event);
|
||||
void OnSize(wxSizeEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
protected:
|
||||
friend void SelectCallback(wxListBox&, wxCommandEvent&);
|
||||
void OnCloseWindow(wxCloseEvent& event);
|
||||
|
||||
private:
|
||||
ScoreFile* m_scoreFile;
|
||||
wxString m_player;
|
||||
wxButton* m_OK;
|
||||
wxButton* m_cancel;
|
||||
wxTextCtrl* m_textField;
|
||||
};
|
||||
|
||||
#endif
|
86
demos/forty/readme.txt
Normal file
86
demos/forty/readme.txt
Normal file
@@ -0,0 +1,86 @@
|
||||
Forty Thieves is a patience game played with two full packs of
|
||||
cards. At the start of the game forty cards are dealt on the
|
||||
eight 'bases' along the top of the window. The object of the
|
||||
game is to place all the cards onto the eight 'foundations'. The
|
||||
foundations are built starting with the ace and adding cards of
|
||||
the same suit up to the king. Cards are dealt from the pack and
|
||||
placed on the discard pile. Cards may be moved from the discard
|
||||
pile or one of the bases to a base or a foundation. Only one
|
||||
card can be moved at a time. Cards can only be placed on a base
|
||||
if the top card of the base is of the same suit and is one
|
||||
higher in pip value or the base is empty e.g. the eight of
|
||||
spades can only be placed on top of the nine of spades.
|
||||
|
||||
When the mouse cursor is over a card which can be moved it
|
||||
changes to the 'hand' cursor. The card can then be moved by
|
||||
double clicking the left button.
|
||||
|
||||
The mouse cursor also changes to a hand when a card is dragged
|
||||
by placing the cursor over the card and holding down the left
|
||||
button. This feature can be enabled and disabled by selecting
|
||||
the 'Helping hand' option from the Edit menu.
|
||||
|
||||
The 'foundations' are the eight piles of cards down the left
|
||||
side of the window. When the game starts these piles are empty.
|
||||
The object of the game is to place all the cards on the
|
||||
foundations. An ace can be placed on any empty foundation. Other
|
||||
cards can only be placed on a foundation if the top card is of
|
||||
the same suit and is one lower in pip value e.g. the three of
|
||||
clubs can be placed on the four of clubs.
|
||||
|
||||
The 'bases' are the ten piles of cards along the top of the
|
||||
window. At the start of the game four cards are dealt face up on
|
||||
each of the bases. A card can be added to a base if the base is
|
||||
empty or if the top card is of the same suit and is one higher
|
||||
in pip value e.g. the queen of hearts can be placed on the king
|
||||
of hearts The top card of a base can be moved onto another base
|
||||
or a foundation.
|
||||
|
||||
Cards can be only moved one at a time. The top card of the pack
|
||||
can be dealt onto discard pile by placing the mouse cursor over
|
||||
the pack and pressing the left button. The number of cards
|
||||
remaining is displayed to the right of the pack.
|
||||
|
||||
Cards can be moved from the discard pile or the bases either by
|
||||
'double-clicking' or by dragging. If the left button is
|
||||
double-clicked when the mouse cursor is over a card and it can
|
||||
move to another pile, it will do so. This is a quick way of
|
||||
moving cards when their destination is unambiguous.
|
||||
|
||||
A card can be dragged by placing the mouse cursor over the card
|
||||
and holding down the left button. The card will follow the mouse
|
||||
cursor until the left button is released. If the card is over a
|
||||
pile on which it can be placed it will be added to that pile,
|
||||
otherwise it will be returned to the pile from which it was
|
||||
dragged.
|
||||
|
||||
One point is scored for every card that is placed on a
|
||||
foundation. Since there are two packs of 52 cards the maximum
|
||||
score is 104. A record is kept of the number of games played,
|
||||
the number of games won, the current score and the average
|
||||
score. This information is displayed at bottom right of the
|
||||
window and is stored on disk between games. A game is deemed to
|
||||
have started if the cards have been dealt and any card has been
|
||||
moved. If the game is abandoned before it is finished (i.e. by
|
||||
starting a new game or closing window) it counts as a lost game.
|
||||
New players can be added by selecting the 'Player' option from
|
||||
the Game menu. A summary of players' scores can be displayed by
|
||||
selecting the 'Scores...' option from the Game menu.
|
||||
|
||||
All moves are recorded and can be undone. To undo a move select
|
||||
the undo menu item from the Edit menu. A quicker way of undoing
|
||||
is to press the right mouse button (it doesn't matter where the
|
||||
mouse cursor is). Right button undo can be enabled and disabled
|
||||
by selecting the 'Right button undo' option from the Edit menu.
|
||||
Pressing the right mouse button with the control key pressed
|
||||
re-does a previously undone move.
|
||||
|
||||
An empty base or two is very useful as it gives the opportunity
|
||||
to unscramble other bases. Try not to build onto kings which
|
||||
obscure valuable cards as it will be difficult to get to them
|
||||
later. The undo facility is very useful for going back and using
|
||||
'hindsight'.
|
||||
|
||||
Don't be put off if you can't win every game. I reckon winning 1
|
||||
in 10 is pretty good (winning 1 in 3 is excellent).
|
||||
|
192
demos/forty/scoredg.cpp
Normal file
192
demos/forty/scoredg.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: scoredg.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_IOSTREAMH
|
||||
#if defined(__WXMSW__) && !defined(__GNUWIN32__) && !defined(__MWERKS__)
|
||||
#include <strstrea.h>
|
||||
#else
|
||||
#include <strstream.h>
|
||||
#endif
|
||||
#else
|
||||
#include <strstream>
|
||||
using namespace std;
|
||||
#endif
|
||||
#include "scorefil.h"
|
||||
#include "scoredg.h"
|
||||
|
||||
class ScoreCanvas : public wxScrolledWindow
|
||||
{
|
||||
public:
|
||||
ScoreCanvas(wxWindow* parent, ScoreFile* scoreFile);
|
||||
virtual ~ScoreCanvas();
|
||||
|
||||
void OnDraw(wxDC& dc);
|
||||
|
||||
private:
|
||||
wxFont* m_font;
|
||||
wxString m_text;
|
||||
};
|
||||
|
||||
|
||||
ScoreCanvas::ScoreCanvas(wxWindow* parent, ScoreFile* scoreFile) :
|
||||
wxScrolledWindow(parent)
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
m_font = wxTheFontList->FindOrCreateFont(12, wxROMAN, wxNORMAL, wxNORMAL);
|
||||
#else
|
||||
m_font = wxTheFontList->FindOrCreateFont(10, wxSWISS, wxNORMAL, wxNORMAL);
|
||||
#endif
|
||||
|
||||
wxArrayString players;
|
||||
scoreFile->GetPlayerList( players);
|
||||
|
||||
ostrstream os;
|
||||
|
||||
os << "Player\tWins\tGames\tScore\n";
|
||||
for (unsigned int i = 0; i < players.Count(); i++)
|
||||
{
|
||||
int wins, games, score;
|
||||
scoreFile->ReadPlayersScore(players[i], wins, games, score);
|
||||
int average = 0;
|
||||
if (games > 0)
|
||||
{
|
||||
average = (2 * score + games) / (2 * games);
|
||||
}
|
||||
|
||||
os << players[i] << '\t'
|
||||
<< wins << '\t'
|
||||
<< games << '\t'
|
||||
<< average << '\n';
|
||||
}
|
||||
os << '\0';
|
||||
char* str = os.str();
|
||||
m_text = str;
|
||||
delete str;
|
||||
}
|
||||
|
||||
ScoreCanvas::~ScoreCanvas()
|
||||
{
|
||||
}
|
||||
|
||||
void ScoreCanvas::OnDraw(wxDC& dc)
|
||||
{
|
||||
dc.SetFont(* m_font);
|
||||
|
||||
const char* str = m_text;
|
||||
unsigned int tab = 0;
|
||||
unsigned int tabstops[] = { 5, 100, 150, 200 };
|
||||
|
||||
// get the line spacing for the current font
|
||||
int lineSpacing;
|
||||
{
|
||||
long w, h;
|
||||
dc.GetTextExtent("Testing", &w, &h);
|
||||
lineSpacing = (int)h;
|
||||
}
|
||||
|
||||
int y = 0;
|
||||
while (*str)
|
||||
{
|
||||
char text[256];
|
||||
char* dest = text;
|
||||
|
||||
while (*str && *str >= ' ') *dest++ = *str++;
|
||||
*dest = '\0';
|
||||
|
||||
dc.DrawText(text, tabstops[tab], y);
|
||||
|
||||
if (*str == '\t')
|
||||
{
|
||||
if (tab < sizeof(tabstops) / sizeof(tabstops[0]) - 1)
|
||||
{
|
||||
tab++;
|
||||
}
|
||||
}
|
||||
else if (*str == '\n')
|
||||
{
|
||||
tab = 0;
|
||||
y += lineSpacing;
|
||||
}
|
||||
if (*str) str++;
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(ScoreDialog, wxDialog)
|
||||
EVT_CLOSE(ScoreDialog::OnCloseWindow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
ScoreDialog::ScoreDialog(
|
||||
wxWindow* parent,
|
||||
ScoreFile* file
|
||||
) :
|
||||
wxDialog(parent, -1, "Scores",
|
||||
wxDefaultPosition, wxSize(310, 200),
|
||||
wxDIALOG_MODAL | wxDEFAULT_DIALOG_STYLE),
|
||||
m_scoreFile(file)
|
||||
{
|
||||
// enable constraints
|
||||
SetAutoLayout (TRUE);
|
||||
|
||||
ScoreCanvas* list = new ScoreCanvas(this, m_scoreFile);
|
||||
m_OK = new wxButton(this, wxID_OK, "OK");
|
||||
|
||||
wxLayoutConstraints* layout;
|
||||
|
||||
// Constrain the OK button
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.SameAs (this, wxLeft, 10);
|
||||
layout->bottom.SameAs (this, wxBottom, 10);
|
||||
layout->height.AsIs();
|
||||
layout->width.AsIs();
|
||||
m_OK->SetConstraints(layout);
|
||||
|
||||
// Constrain the list of players
|
||||
layout = new wxLayoutConstraints;
|
||||
layout->left.SameAs (this, wxLeft, 10);
|
||||
layout->right.SameAs (this, wxRight, 10);
|
||||
layout->top.SameAs (this, wxTop, 10);
|
||||
layout->bottom.SameAs (m_OK, wxTop, 10);
|
||||
list->SetConstraints(layout);
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
ScoreDialog::~ScoreDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void ScoreDialog::Display()
|
||||
{
|
||||
Show(TRUE);
|
||||
}
|
||||
|
||||
void ScoreDialog::OnCloseWindow(wxCloseEvent& event)
|
||||
{
|
||||
EndModal(wxID_OK);
|
||||
}
|
34
demos/forty/scoredg.h
Normal file
34
demos/forty/scoredg.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: scoredg.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _SCOREDG_H_
|
||||
#define _SCOREDG_H_
|
||||
|
||||
class ScoreDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
ScoreDialog(wxWindow* parent, ScoreFile* file);
|
||||
virtual ~ScoreDialog();
|
||||
|
||||
void Display();
|
||||
|
||||
protected:
|
||||
void OnCloseWindow(wxCloseEvent& event);
|
||||
|
||||
private:
|
||||
ScoreFile* m_scoreFile;
|
||||
wxButton* m_OK;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif
|
183
demos/forty/scorefil.cpp
Normal file
183
demos/forty/scorefil.cpp
Normal file
@@ -0,0 +1,183 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: scorefil.cpp
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 14th May 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation
|
||||
#pragma interface
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "wx/textfile.h"
|
||||
#include "wx/config.h"
|
||||
#include "wx/fileconf.h"
|
||||
|
||||
#include "scorefil.h"
|
||||
|
||||
|
||||
ScoreFile::ScoreFile(const char* appName)
|
||||
{
|
||||
#if 0
|
||||
wxString filename;
|
||||
m_configFilename << "/usr/local/share/" << appName << ".scores";
|
||||
if (access(m_configFilename, F_OK) == 0)
|
||||
{
|
||||
if (access(m_configFilename, R_OK | W_OK) != 0)
|
||||
{
|
||||
// file is not r/w - use local file instead
|
||||
m_configFilename = wxFileConfig::GetLocalFileName(appName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int fd = creat(m_configFilename, 0666);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
// failed to create file - use local file instead
|
||||
m_configFilename = wxFileConfig::GetLocalFileName(appName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ensure created file has rw-rw-rw permissions
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_config = new wxConfig(appName, "wxWindows", appName, "", wxCONFIG_USE_LOCAL_FILE); // only local
|
||||
}
|
||||
|
||||
ScoreFile::~ScoreFile()
|
||||
{
|
||||
delete m_config;
|
||||
#ifdef __WXGTK__
|
||||
// ensure score file has rw-rw-rw permissions
|
||||
// (wxFileConfig sets them to rw-------)
|
||||
chmod(m_configFilename, 0666);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ScoreFile::GetPlayerList( wxArrayString &list )
|
||||
{
|
||||
m_config->SetPath("/Players");
|
||||
int length = m_config->GetNumberOfGroups();
|
||||
|
||||
if (length <= 0) return;
|
||||
|
||||
wxString player;
|
||||
long index, i = 0;
|
||||
if (m_config->GetFirstGroup(player, index))
|
||||
{
|
||||
list.Add( player );
|
||||
i++;
|
||||
while (m_config->GetNextGroup(player, index))
|
||||
{
|
||||
list.Add( player );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculate an encrypted check number to prevent tampering with
|
||||
// score file
|
||||
long ScoreFile::CalcCheck(const char* name, int p1, int p2, int p3)
|
||||
{
|
||||
long check = 0;
|
||||
while (*name)
|
||||
{
|
||||
check = (check << 1) ^ (long)*name++;
|
||||
check = ((check >> 23) ^ check) & 0xFFFFFF;
|
||||
}
|
||||
check = (check << 1) ^ (long)p1;
|
||||
check = ((check >> 23) ^ check) & 0xFFFFFF;
|
||||
check = (check << 1) ^ (long)p2;
|
||||
check = ((check >> 23) ^ check) & 0xFFFFFF;
|
||||
check = (check << 1) ^ (long)p3;
|
||||
check = ((check >> 23) ^ check) & 0xFFFFFF;
|
||||
return check;
|
||||
}
|
||||
|
||||
wxString ScoreFile::GetPreviousPlayer() const
|
||||
{
|
||||
wxString result;
|
||||
m_config->SetPath("/General");
|
||||
m_config->Read("LastPlayer", &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ScoreFile::ReadPlayersScore(
|
||||
const char* player,
|
||||
int& wins,
|
||||
int& games,
|
||||
int& score)
|
||||
{
|
||||
long check;
|
||||
long myWins, myGames, myScore;
|
||||
|
||||
games = wins = score = 0;
|
||||
|
||||
m_config->SetPath("/Players");
|
||||
m_config->SetPath(player);
|
||||
if (m_config->Read("Score", &myScore, 0L) &&
|
||||
m_config->Read("Games", &myGames, 0L) &&
|
||||
m_config->Read("Wins", &myWins, 0L) &&
|
||||
m_config->Read("Check", &check, 0L))
|
||||
{
|
||||
if (check != CalcCheck(player, myGames, myWins, myScore))
|
||||
{
|
||||
wxMessageBox("Score file corrupted", "Warning",
|
||||
wxOK | wxICON_EXCLAMATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
games = myGames;
|
||||
wins = myWins;
|
||||
score = myScore;
|
||||
}
|
||||
}
|
||||
WritePlayersScore(player, wins, games, score);
|
||||
}
|
||||
|
||||
|
||||
void ScoreFile::WritePlayersScore(const char* player, int wins, int games, int score)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
m_config->SetPath("/General");
|
||||
m_config->Write("LastPlayer", wxString(player)); // Without wxString tmp, thinks it's bool in VC++
|
||||
|
||||
m_config->SetPath("/Players");
|
||||
m_config->SetPath(player);
|
||||
m_config->Write("Score", (long)score);
|
||||
m_config->Write("Games", (long)games);
|
||||
m_config->Write("Wins", (long)wins);
|
||||
m_config->Write("Check", CalcCheck(player, games, wins, score));
|
||||
}
|
||||
}
|
37
demos/forty/scorefil.h
Normal file
37
demos/forty/scorefil.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: scorefil.h
|
||||
// Purpose: Forty Thieves patience game
|
||||
// Author: Chris Breeze
|
||||
// Modified by:
|
||||
// Created: 21/07/97
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 1993-1998 Chris Breeze
|
||||
// Licence: wxWindows licence
|
||||
//---------------------------------------------------------------------------
|
||||
// Last modified: 22nd July 1998 - ported to wxWindows 2.0
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _SCOREFILE_H_
|
||||
#define _SCOREFILE_H_
|
||||
|
||||
#include <wx/config.h>
|
||||
|
||||
class wxConfig;
|
||||
|
||||
class ScoreFile {
|
||||
public:
|
||||
ScoreFile(const char* appName);
|
||||
virtual ~ScoreFile();
|
||||
|
||||
void GetPlayerList( wxArrayString &list );
|
||||
wxString GetPreviousPlayer() const;
|
||||
|
||||
void ReadPlayersScore(const char* player, int& wins, int& games, int &score);
|
||||
void WritePlayersScore(const char* player, int wins, int games, int score);
|
||||
|
||||
private:
|
||||
long CalcCheck(const char* name, int p1, int p2, int p3);
|
||||
wxString m_configFilename;
|
||||
wxConfig* m_config;
|
||||
};
|
||||
|
||||
#endif
|
BIN
demos/forty/symbols.bmp
Normal file
BIN
demos/forty/symbols.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 662 B |
37
demos/forty/symbols.xbm
Normal file
37
demos/forty/symbols.xbm
Normal file
@@ -0,0 +1,37 @@
|
||||
#define Symbols_width 79
|
||||
#define Symbols_height 50
|
||||
static char Symbols_bits[] = {
|
||||
0x08,0x84,0x0d,0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x1c,0xce,0x9f,0x03,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x2a,0xdf,0xdf,0x07,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x80,0x2a,0x9f,0xcf,0x07,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x08,0x0e,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x1c,0x04,0x82,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x1c,0x04,0x82,0x03,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x08,0x0e,0x07,0x01,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x2a,0x9f,0xcf,0x07,0x00,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0xff,0x0f,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x2a,0xdf,0xdf,0x07,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x1c,0xce,0x9f,0x03,0x00,0x00,0x00,0x00,0x00,0x80,0x08,0x84,0x0d,0x01,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x70,0x00,0x01,0x63,0x40,0x00,0x00,0x00,0x00,0x80,
|
||||
0xf8,0x80,0x83,0xf7,0xe0,0x00,0x00,0x00,0x00,0x80,0xf8,0x80,0xc3,0xff,0xf1,
|
||||
0x01,0x00,0x00,0x00,0x80,0x70,0xc0,0xc7,0xff,0xf9,0x03,0x00,0x00,0x00,0x80,
|
||||
0x26,0xe3,0xcf,0xff,0xfd,0x07,0x00,0x00,0x00,0x80,0xaf,0xf7,0xdf,0xff,0xff,
|
||||
0x0f,0x00,0x00,0x00,0x80,0xff,0xe7,0x8f,0xff,0xfe,0x0f,0x00,0x00,0x00,0x80,
|
||||
0xaf,0xc7,0x07,0x7f,0x5e,0x0f,0x00,0x00,0x00,0x80,0x26,0x83,0x03,0x3e,0x4c,
|
||||
0x06,0x00,0x00,0x00,0x80,0x70,0x80,0x03,0x1c,0xe0,0x00,0x00,0x00,0x00,0x80,
|
||||
0xfc,0x01,0x01,0x08,0xf8,0x03,0x00,0x00,0x00,0x80,0xfc,0x01,0x01,0x08,0xf8,
|
||||
0x03,0x00,0x00,0x00,0x80,0x70,0x80,0x03,0x1c,0xe0,0x00,0x00,0x00,0x00,0x80,
|
||||
0x26,0x83,0x03,0x3e,0x4c,0x06,0x00,0x00,0x00,0x80,0xaf,0xc7,0x07,0x7f,0x5e,
|
||||
0x0f,0x00,0x00,0x00,0x80,0xff,0xe7,0x8f,0xff,0xfe,0x0f,0x00,0x00,0x00,0x80,
|
||||
0xaf,0xf7,0xdf,0xff,0xff,0x0f,0x00,0x00,0x00,0x80,0x26,0xe3,0xcf,0xff,0xfd,
|
||||
0x07,0x00,0x00,0x00,0x80,0x70,0xc0,0xc7,0xff,0xf9,0x03,0x00,0x00,0x00,0x80,
|
||||
0xf8,0x80,0xc3,0xff,0xf1,0x01,0x00,0x00,0x00,0x80,0xf8,0x80,0x83,0xf7,0xe0,
|
||||
0x00,0x00,0x00,0x00,0x80,0x70,0x00,0x01,0x63,0x40,0x00,0x00,0x00,0x00,0x80,
|
||||
0x0c,0xe7,0x43,0x3e,0xe7,0x73,0x5c,0xe6,0x73,0xa2,0x92,0x08,0x61,0x82,0x00,
|
||||
0x8a,0x62,0x09,0x89,0x92,0x21,0x88,0x50,0x9e,0x00,0x89,0x62,0x09,0x89,0x8a,
|
||||
0x21,0xc6,0x49,0xa0,0x87,0x70,0x7c,0x09,0x89,0x86,0x3f,0x01,0xfa,0xa0,0x88,
|
||||
0x88,0x60,0x09,0xa9,0x8a,0xa1,0x20,0x42,0xa2,0x88,0x88,0x50,0x29,0x49,0x92,
|
||||
0xa1,0xcf,0x41,0x1c,0x87,0x70,0x48,0xc6,0xb0,0xa2,0xa1,0xcf,0x11,0x1c,0x87,
|
||||
0x70,0x88,0x89,0x69,0xa2,0x21,0x28,0x12,0xa2,0x88,0x88,0x44,0x4a,0x92,0xa4,
|
||||
0x3f,0x24,0xf8,0x82,0x88,0x88,0x42,0x4a,0xa8,0xa8,0x21,0xc3,0x91,0x82,0x8f,
|
||||
0x70,0x5e,0x4a,0x88,0xb0,0xa1,0x80,0x50,0x3c,0x48,0x88,0x62,0x4a,0x88,0xa8,
|
||||
0x92,0x48,0x30,0x20,0x28,0x88,0x62,0x4a,0x88,0xa4,0x0c,0xe7,0x13,0x3e,0xe7,
|
||||
0x73,0x9c,0xe9,0x73,0xa2};
|
60
demos/forty/symbols.xpm
Normal file
60
demos/forty/symbols.xpm
Normal file
@@ -0,0 +1,60 @@
|
||||
/* XPM */
|
||||
static char *symbols[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 79 50 3 1",
|
||||
/* colors */
|
||||
". c #ffffff",
|
||||
"* c #ff0000",
|
||||
"# c #000000",
|
||||
/* pixels */
|
||||
"...#......*....**.**....#......................................................",
|
||||
"..###....***..*******..###.....................................................",
|
||||
".#.#.#..*****.*******.#####....................................................",
|
||||
"#######**************#######...................................................",
|
||||
".#.#.#..*****..*****..#####....................................................",
|
||||
"...#.....***....***.....#......................................................",
|
||||
"..###.....*......*.....###.....................................................",
|
||||
"..###.....*......*.....###.....................................................",
|
||||
"...#.....***....***.....#......................................................",
|
||||
".#.#.#..*****..*****..#####....................................................",
|
||||
"#######**************#######...................................................",
|
||||
".#.#.#..*****.*******.#####....................................................",
|
||||
"..###....***..*******..###.....................................................",
|
||||
"...#......*....**.**....#......................................................",
|
||||
"....###.........*.......**...**.......#........................................",
|
||||
"...#####.......***.....****.****.....###.......................................",
|
||||
"...#####.......***....***********...#####......................................",
|
||||
"....###.......*****...***********..#######.....................................",
|
||||
".##..#..##...*******..***********.#########....................................",
|
||||
"####.#.####.*********.***********###########...................................",
|
||||
"###########..*******...*********.###########...................................",
|
||||
"####.#.####...*****.....*******..####.#.####...................................",
|
||||
".##..#..##.....***.......*****....##..#..##....................................",
|
||||
"....###........***........***........###.......................................",
|
||||
"..#######.......*..........*.......#######.....................................",
|
||||
"..#######.......*..........*.......#######.....................................",
|
||||
"....###........***........***........###.......................................",
|
||||
".##..#..##.....***.......*****....##..#..##....................................",
|
||||
"####.#.####...*****.....*******..####.#.####...................................",
|
||||
"###########..*******...*********.###########...................................",
|
||||
"####.#.####.*********.***********###########...................................",
|
||||
".##..#..##...*******..***********.#########....................................",
|
||||
"....###.......*****...***********..#######.....................................",
|
||||
"...#####.......***....***********...#####......................................",
|
||||
"...#####.......***.....****.****.....###.......................................",
|
||||
"....###.........*.......**...**.......#........................................",
|
||||
"..##....###..#####....#..#####..###..#####..###...###.#..##..#####..###..#...#.",
|
||||
".#..#..#...#....#....##..#.....#.........#.#...#.#...##.#..#....#..#...#.#..#..",
|
||||
"#....#.....#...#....#.#..####..#........#..#...#.#...##.#..#....#..#...#.#.#...",
|
||||
"#....#...##...###..#..#......#.####....#....###...#####.#..#....#..#...#.##....",
|
||||
"######..#........#.#####.....#.#...#...#...#...#.....##.#..#....#..#.#.#.#.#...",
|
||||
"#....#.#.....#...#....#..#...#.#...#...#...#...#....#.#.#..#.#..#..#..#..#..#..",
|
||||
"#....#.#####..###.....#...###...###....#....###....#..#..##...##....##.#.#...#.",
|
||||
"#....#.#####..###...#.....###...###....#....###....#...##..#...##..#.##..#...#.",
|
||||
"#....#.....#.#...#..#....#...#.#...#...#...#...#..#...#..#.#..#..#..#..#..#..#.",
|
||||
"######....#..#.....#####.#.....#...#...#...#...#.#....#..#.#..#....#.#.#...#.#.",
|
||||
"#....#..##....###...#..#.#.....#####...#....###..####.#..#.#..#....#...#....##.",
|
||||
"#....#.#.......#....#.#...####.....#..#....#...#.#...##..#.#..#....#...#...#.#.",
|
||||
".#..#..#...#..#.....##.......#.....#.#.....#...#.#...##..#.#..#....#...#..#..#.",
|
||||
"..##....###..#####..#....#####..###..#####..###...###..##..#.#####..###..#...#."
|
||||
};
|
Reference in New Issue
Block a user