using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using Sprite;
using PicTray;
/// todo
/// - intro animation
namespace Clue_CS2010
{
#region "enumerated types"
public enum enuAccuseAnimationMode
{
endAccusation,
drawAccusation,
prepareToShowCards,
showCards,
hideCards,
retractCards,
withdrawAccusingSuspect,
showNewspaper
}
public enum enuAILevel { stupid, dull, average, bright, genius, _numAILevels };
public enum enuButtons { MakeSuggestion_Cancel, MakeSuggestion_Ok, RespondToSuggestion_Ok, MouseOver, _numButtons };
public enum enuCards
{
MissScarlet = 0, ColMustard, MrsWhite, RevGreen, MrsPeacock, ProfPlum,
Knife, Candlestick, Revolver, Rope, LeadPipe, Wrench,
Study, Hall, Lounge, DiningRoom, Kitchen, BallRoom, Conservatory, BilliardRoom, Library,
_numCards, Unknown, NoCardShown
};
public enum enuCardType { weapon = 0, room, Suspect, _numCardTypes };
public enum enuDealCardsMode
{
getReady,
SortCardsIntotypes,
gatherTypes,
spreadWeaponCardsFaceUp,
flipWeaponcards,
shuffleWeaponCards,
gatherFaceDownWeapons,
spreadWeapondsCardsFaceDown,
selectWeapon,
gatherFaceDownWeapons_LessMurderWeapon,
spreadSuspectCardsFaceUp,
flipSuspectcards,
shuffleSuspectCards,
gatherFaceDownSuspects,
spreadSuspectdsCardsFaceDown,
selectSuspect,
gatherFaceDownSuspects_LessMurderSuspect,
spreadRoomCardsFaceUp,
flipRoomcards,
shuffleRoomCards,
gatherFaceDownRooms,
spreadRoomdsCardsFaceDown,
selectRoom,
gatherFaceDownRooms_LessMurderRoom,
shuffleCards,
joinCardsAfterShuffle,
dealToPlayers,
moveMurderCardsToCenter,
endDealCardsAnimation
};
public enum enuDir { north = 0, east, south, west, secretPassage };
public enum enuFloor { tile = 0, room, door, invalid };
public enum enuIntroAnimationMode
{
moveToBawdyMansion,
moveToRat,
movetoCKLovesVP,
moveToBritneyWasHere,
moveToSpider,
moveToCheese,
moveToCat,
moveToWaldo,
moveToJessicaRabbit,
moveToWrittenBy,
moveToChristKennedy,
moveToYear,
moveToEnd,
_numIntroMode
};
public enum enuIntroAnimationSprites
{
waldo,
Jessica_Rabbit,
RatProtester,
_NumIntroAnimationSprites
};
public enum enuMode
{
idle,
dealCards,
Accuse,
Accuse_Animation,
chooseCharacter,
warnPlayerNextTurn,
beginTurn,
gameOver,
rollDie_begin,
rollDie_animate,
rollDie_end,
showAllowableMoves,
animateMove,
Suggest,
AISuggestionComplete,
animateIntroduction,
animateSummonSuspect,
animateSummonWeapon,
animateSecretPassage,
respondToSuggestion,
playerChoosesCardToShow,
playerTurnIdle,
endTurn,
any
};
public enum enuNote { blank, X, check, question, _numNotes, shown };
public enum enuRooms { Study, Hall, Lounge, DiningRoom, Kitchen, BallRoom, Conservatory, BilliardRoom, Library, _numRooms, start, tiles };
public enum enuSuspects { MissScarlet = 0, ColMustard, MrsWhite, RevGreen, MrsPeacock, ProfPlum, _numSuspects };
public enum enuWeapons { Knife = 0, Candlestick, Revolver, Rope, LeadPipe, Wrench, _numWeapons };
#endregion
#region "structures"
public struct udtMurder
{
public enuSuspects eSuspect;
public enuRooms eRoom;
public enuWeapons eWeapon;
}
public struct udtAnimationSummons
{
public Point ptStart;
public Point ptEnd;
public Point ptMidway;
public int intStepCounter;
public int intMaxSteps;
public double dblAngleBetweenPoints;
public double dblDistanceBetweenPoints;
public bool bolMoveToCenterOfScreen;
}
public struct udtAnimationSecretPassge
{
public Point ptStart;
public Point ptEnd;
public Point ptMidway;
public int intStepCounter;
public int intMaxSteps;
public double dblAngleBetweenPoints;
public double dblDistanceBetweenPoints;
public bool bolMoveToCenterOfScreen;
public enuRooms eRoom_Start;
public enuRooms eRoom_End;
}
public struct udtSuggestionAnimation
{
public int intProveSuggestionCycleCounter;
}
public struct udtAnimationInfo
{
public Point ptStart;
public Point ptEnd;
public Point ptPos;
public int intStep;
public int intMaxSteps;
public double dblTravelAngle;
public double dblTravelDistance;
public double dblTravelInitialVelocity;
public double dblTravelAcceleration;
public Point velTravel;
public double dblAngleFacing;
public double dblAngleTurning;
public double dblAngleTurningAttenuation;
public double dblSizeFactor;
public Bitmap bmpGray;
public Bitmap bmp;
}
public struct udtAccusation_Animation
{
public classCard[] cAnimatedCards;
public int intAnimationStep;
public bool bolInit;
public Bitmap bmpAccusationBoard;
public Bitmap bmpShadedAccusationBoard;
public Bitmap bmpAccusationForegroundGray;
public Bitmap bmpAccusationForeground;
public enuAccuseAnimationMode _eMode;
public udtMurder udrAccusation;
public udtAnimationInfo[] udrElements;
public udtAnimationInfo[] udrFloodlights;
public udtAccusation_Animation_RotatingNewspaper udrNewspaper;
public enuMode eRestoreMode;
}
public struct udtIntro_Animation
{
public int intAnimationStep;
public bool bolInit;
public enuIntroAnimationMode eMode;
//public udtAnimationInfo[] udrMice;
public udtIntro_Animation_Board udrBoardUnderLense;
public Bitmap bmpBoard;
public udtIntro_MagnifyingGlass udrMagnifyingGlass;
public classRotatedImage[] cBmpMice;
public udtIntro_Animation_Sprites[] sprites;
}
public struct udtIntro_Animation_Sprites
{
public classSprite cSprite;
public int intConfiguration;
public int intConfigurationStep;
public int intMaxSteps;
public int intStepCounter;
public Sprite.enuMirror eMirror;
public udtAnimationInfo udrAniInfo;
}
public struct udtIntro_Animation_Board
{
public udtIntro_Animation_BoardParcel[,] udrParcels;
public Size szArray;
public Size szParcels;
}
public struct udtIntro_Animation_BoardParcel
{
public Bitmap bmp;
public Rectangle rec;
}
public struct udtIntro_MagnifyingGlass
{
public Point ptStart;
public Point ptEnd;
public Point ptPos;
public int intStep;
public int intMaxSteps;
public int intHoverStep;
public int intHoverMax;
public double dblTravelAngle;
public double dblTravelDistance;
public Point velTravel;
public double dblSizeFactor;
public double dblSizeFactor_Start;
public double dblSizeFactor_End;
public Bitmap bmpLense;
public Bitmap bmpHandle;
public Color clrBackground;
public Color clrLense;
public Point ptCenterLense;
}
public struct udtAccusation_Animation_RotatingNewspaper
{
public classRotatedImage cBmp;
public int intImage;
public Point ptPos;
public double dblSizeFactor;
}
public struct udtMoveAnimationInfo
{
public string strPath;
public int intAnimationStep;
public Bitmap bmpAnimationBoard;
public Point ptMouseTile;
public Point ptAnimationMove;
public Point ptImage;
public Rectangle recPiece;
public classSuspect cSus;
}
public struct udtRollDieInfo
{
public int intDieValue;
public int intDieWidth;
public int intMaxVel;
public int intVelFactor;
public int intImageIndex;
public Bitmap bmpCurrent;
public double dblVelocityAttenuationFactor;
public int intRightMost;
public int intLowerMost;
public double dblVel;
public double dblAngle;
public double dblXVel;
public double dblYVel;
public int intRollCount;
public int intRollAnimation;
public Point ptDie;
}
/// <summary>
/// used to track sequence of suspects that follow me in order of play
/// </summary>
public struct udtSuggestionAI_perSuspect
{
public enuSuspects eSuspect;
public udtSuggestionAI_frequenCards[] udrRoomsMystery; // list of mystery Rooms which this suspect may have
public udtSuggestionAI_frequenCards[] udrWeaponCardsMystery; // list of mystery Weapons which this suspect may have
public udtSuggestionAI_frequenCards[] udrSuspectCardsMystery; // list of mystery Suspects which this suspect may have
}
/// <summary>
/// number of suspects who may have any given card
/// </summary>
public struct udtSuggestionAI_frequenCards
{
public enuCards eCards;
public int intNumMystery;
}
/// <summary>
/// information used to make a more informed suggestion
/// </summary>
public struct udtSuggestionAI
{
public udtSuggestionAI_perSuspect[] suspectMysteryInfo; // sequence of suspects that follow me in order of play
// suspect's name, list of rooms cards suspect may have, list of weapons cards (ibid), list of suspect cards (ibid)
public udtSuggestionAI_frequenCards[] udrRoomCardsMysteryFrequency; // array of room cards ordered in number of suspects which may have these cards
public udtSuggestionAI_frequenCards[] udrWeaponMysteryFrequency; // same : weapon cards
public udtSuggestionAI_frequenCards[] udrSuspectMysteryFrequency; // same : Suspect cards
}
public struct udtTypeOrder
{
public classCard[] cWeapons;
public classCard[] cSuspects;
public classCard[] cRooms;
}
public struct udtAnimateDealCards
{
public enuDealCardsMode _eMode;
public classCard[] cCardsCurrentAnimation;
public udtTypeOrder udrTypeOrder;
public int intAnimationCounter;
public string strCards;
public bool bolInit;
public bool bolQuitAnimation;
public udtAnimateDealCards_Shuffle udrShuffle;
}
public struct udtAnimateDealCards_Shuffle
{
public Point ptCentralShufflePos;
public int intMaxDistance;
public int intTimeShuffled;
public int intMaxShuffle;
}
#endregion
public partial class formClue : Form
{
#region "constants"
public const double dblTwoPi = Math.PI * 2.0;
#endregion
#region "debug variables"
//public string strDebugFilename;
///// <summary>
///// when true : load sprites from c:\sprites\
///// when false : search for sprite files by going to parent until(but not including) root of drive starting for current-directory
///// </summary>
//public bool bolDebug = true;
#endregion
#region "objects"
public classMath cLibMath = new classMath();
public classSpriteMaker spriteMaker = new classSpriteMaker();
public PictureBox picBoard = new PictureBox();
Button[] btnPlayerResponse = new Button[3];
public ProgressBar proBar = new ProgressBar();
MenuStrip mnu = new MenuStrip();
public classButton[] cButtons;
public Size sz;
public Label lblSizer = new Label();
public classPicTray_V2 cLibPicTraySuspects = new classPicTray_V2();
public classPicTray_V2 cLibPicTrayWeapons = new classPicTray_V2();
public classPicTray_V2 cLibPicTrayRooms = new classPicTray_V2();
public System.Windows.Forms.Timer tmrDelay = new System.Windows.Forms.Timer();
public System.Windows.Forms.Timer tmrAutoProceed = new System.Windows.Forms.Timer();
public System.Windows.Forms.Timer tmrNextPlayer = new System.Windows.Forms.Timer();
public Random rnd = new Random();
Label lblInitializing = new Label();
System.Windows.Forms.Timer tmrInit = new System.Windows.Forms.Timer();
#endregion
#region "Variables"
public Bitmap bmpBoard, bmpSuggestionBoard, bmpGameBoard, bmpDealAnimationBoard, bmpDealAnimationBoard_Base;
Bitmap bmpBaize = Clue_CS2010.Properties.Resources.baize;
Bitmap bmpSuggestionBubble = Clue_CS2010.Properties.Resources.SuggestionBubble;
Bitmap bmpCardBack = Clue_CS2010.Properties.Resources.cardback;
Bitmap bmpBannerNoCard = Clue_CS2010.Properties.Resources.NoCardsToShow;
Bitmap bmpBannerCardToShow = Clue_CS2010.Properties.Resources.CanShowACard;
formInstructions frmInstructions;
Bitmap bmpResponseBubble;
public Bitmap bmpNotebook;
public Bitmap[] bmpPieces = new Bitmap[(int)enuSuspects._numSuspects];
public Bitmap[] bmpSuspects = new Bitmap[(int)enuSuspects._numSuspects];
public Bitmap[] bmpWeapons_PicTray = new Bitmap[(int)enuWeapons._numWeapons];
public Bitmap[] bmpWeapons_Board = new Bitmap[(int)enuWeapons._numWeapons];
public Bitmap[] bmpRooms = new Bitmap[(int)enuRooms._numRooms];
public classCard cCardUnknown;
public classCard[] cCards;
public classSuspect[] cSuspects;
public classRoom[] cRooms;
public classWeapon[] cWeapons;
public Color[] clrSuspects;
public enuCards[] eValidPlayerResponseCards;
Rectangle recBannerButton;
classNote[,] cPlayerNotes = new classNote[(int)enuSuspects._numSuspects, (int)enuCards._numCards];
classNote cMouseOverNote;
enuMode _eMode = enuMode.chooseCharacter;
udtMoveAnimationInfo udrMoveAnimationInfo;
string strCardsDealt;
Point[] ptAnimationTypeStackPos;
Point ptMouseTile;
Point ptMousePos;
public Point ptBoardTL = new Point(26, 7);
Point[] ptSetAI;
Point[] ptRoomCenters;
Point ptSuggestionBubbleTL, ptResponseBubbleTL;
bool _bolDisableMouseClickBoard = false;
bool bolHideOptions = false;
public bool bolAutoProceed = false;
public int intSuspectTurn;
public int intNumTurns = 0;
int intBaseAutoProceedInterval = 3500;
double dblSpeedFactor = 1.0;
public classRotatedImage[] cBmpDie;
public udtRollDieInfo udrRollDieInfo;
public udtSuggestionAnimation udrSuggestionAnimation;
public udtAnimationSummons udrAniSummWeapon;
public udtAnimationSummons udrAniSummSuspect;
public udtAnimationSecretPassge udrAniSecretPassage;
public udtIntro_Animation udrAniIntro;
public udtMurder udrMurder = new udtMurder();
public udtMurder udrSuggestion = new udtMurder();
public udtAnimateDealCards udrAnimateDealCards;
public udtAccusation_Animation udrAniAccusation;
/// flood-lights accusation animation variables
Bitmap bmpFloodlights;
Color clrFloordlights = Color.Red;
Color clrField = Color.Blue;
Brush br;
bool bolInit = false;
#endregion
public formClue()
{
InitializeComponent();
bmpNotebook = new Bitmap(Clue_CS2010.Properties.Resources.notebook);
bmpBoard = new Bitmap(Clue_CS2010.Properties.Resources.ClueBoardMarble);
sz = new Size(Clue_CS2010.Properties.Resources.ClueFloor.Width, Clue_CS2010.Properties.Resources.ClueFloor.Height);
picBoard.Image = bmpBoard;
picBoard.Refresh();
PlaceControls();
proBar.Visible = true; proBar.Maximum = 210;
tmrInit.Interval = 5;
tmrInit.Tick += new EventHandler(tmrInit_Tick);
tmrInit.Enabled = true;
}
public bool bolDisableMouseClickBoard
{
get { return _bolDisableMouseClickBoard; }
set
{
_bolDisableMouseClickBoard = value;
}
}
public void advanceProBar()
{
proBar.Value = (proBar.Value + 1) % proBar.Maximum;
}
void tmrInit_Tick(object sender, EventArgs e)
{
tmrInit.Enabled = false;
Location = new Point(0, 0);
Size = Screen.PrimaryScreen.WorkingArea.Size;
Refresh();
//initIntroMice(); advanceProBar();
initMenu(); advanceProBar();
initDieImages(); advanceProBar();
initPieces(); advanceProBar();
initSuspects(); advanceProBar();
initWeapons(); advanceProBar();
initColors(); advanceProBar();
initRooms(); advanceProBar();
resetPlayerNotes(); advanceProBar();
initSetAIGroupBox(); advanceProBar();
initCards(); advanceProBar();
initAnimationIntroBehindTheLenseImages();
eMode = (enuMode)0;
initResponseBubble(); advanceProBar();
bmpSuggestionBubble.MakeTransparent();
bmpBannerCardToShow.MakeTransparent();
bmpBannerNoCard.MakeTransparent();
cButtons = new classButton[(int)enuButtons._numButtons];
tmrNextPlayer.Interval = 5;
tmrNextPlayer.Tick += new EventHandler(tmrNextPlayer_Tick);
advanceProBar();
ptAnimationTypeStackPos = new Point[3];
ptAnimationTypeStackPos[(int)enuCardType.room] = new Point((int)(bmpBoard.Width * .1), (int)(bmpBoard.Height * .25));
ptAnimationTypeStackPos[(int)enuCardType.Suspect] = new Point((int)(bmpBoard.Width * .1), (int)(bmpBoard.Height * .5));
ptAnimationTypeStackPos[(int)enuCardType.weapon] = new Point((int)(bmpBoard.Width * .1), (int)(bmpBoard.Height * .75));
tmrDelay.Tick += new EventHandler(tmrDelay_Tick);
//strDebugFilename = System.IO.Directory.GetCurrentDirectory() + "\\AI test results.txt";
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
Size = Screen.PrimaryScreen.WorkingArea.Size;
Activated += new EventHandler(formClue_Activated);
advanceProBar();
resetPlayerNotes(); resetSuspects(enuSuspects.MissScarlet);
advanceProBar();
#region "init tray : cLibPicTrayRooms"
{
picBoard.Controls.Add(cLibPicTrayRooms);
cLibPicTrayRooms.BackColor = Color.Transparent;
cLibPicTrayRooms.tmrRotate.Tick += new EventHandler(cLibPicTraySuspectTmrRotate_Tick);
for (enuRooms eRoomCounter = (enuRooms)0; eRoomCounter < enuRooms._numRooms; eRoomCounter++)
cLibPicTrayRooms.addImageToTray(new Bitmap(cCards[(int)classCard.getECardFromERoom(eRoomCounter)].cBmp.getImage(0)), eRoomCounter.ToString());
cLibPicTrayRooms.Visible = false;
}
#endregion
advanceProBar();
#region "init tray : cLibPicTraySuspects"
{
picBoard.Controls.Add(cLibPicTraySuspects);
cLibPicTraySuspects.Options.BackColor = Color.Transparent;
cLibPicTraySuspects.RoundImages = true;
cLibPicTraySuspects.tmrRotate.Tick += new EventHandler(cLibPicTraySuspectTmrRotate_Tick);
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
cLibPicTraySuspects.addImageToTray(bmpSuspects[(int)eSuspectCounter], eSuspectCounter.ToString());
cLibPicTraySuspects.Visible = false;
}
#endregion
advanceProBar();
#region "init tray : cLibPicTrayWeapons"
{
picBoard.Controls.Add(cLibPicTrayWeapons);
cLibPicTrayWeapons.Options.BackColor = Color.Transparent;
cLibPicTrayWeapons.Location = new Point(355, 0);
cLibPicTrayWeapons.RoundImages = true;
cLibPicTrayWeapons.tmrRotate.Tick += new EventHandler(cLibPicTrayWeaponTmrRotate_Tick);
for (enuWeapons eSuspectCounter = (enuWeapons)0; eSuspectCounter < enuWeapons._numWeapons; eSuspectCounter++)
cLibPicTrayWeapons.addImageToTray(new Bitmap(bmpWeapons_PicTray[(int)eSuspectCounter]), eSuspectCounter.ToString());
cLibPicTrayWeapons.Visible = false;
}
#endregion
// init accusation animation variables
bmpFloodlights = new Bitmap(bmpBoard.Width, bmpBoard.Height);
using (Graphics g = Graphics.FromImage(bmpFloodlights))
g.FillRectangle(new SolidBrush(clrField), new Rectangle(0, 0, bmpBoard.Width, bmpBoard.Height));
bmpFloodlights.MakeTransparent(clrFloordlights);
br = new SolidBrush(clrFloordlights);
advanceProBar();
commitMurder(); dealCards();
eMode = enuMode.idle; eDealMode = enuDealCardsMode.SortCardsIntotypes;
lblInitializing.Visible =
proBar.Visible = false;
bolInit = true;
eMode = enuMode.animateIntroduction;
}
void formClue_Activated(object sender, EventArgs e)
{
Location = new Point(0, 0);
}
#region "timers"
public void setDelayTimer(int intMilliseconds)
{
int intNewInterval = (int)(intMilliseconds * dblSpeedFactor);
if (intNewInterval < 1)
intNewInterval = 1;
tmrDelay.Interval = intNewInterval;
tmrDelay.Enabled = false;
tmrDelay.Enabled = true;
}
void tmrAutoProceed_Tick(object sender, EventArgs e)
{
autoProceedEnabled = false;
switch (eMode)
{
case enuMode.playerChoosesCardToShow:
if (eValidPlayerResponseCards.Length == 1)
btnPlayerResponse_Click((object)btnPlayerResponse[0], new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, 1, 1, 1));
else
PlayerChoosesCardToShowBannerClick();
break;
default:
btnRespondSuggestion_OK_click();
break;
}
}
void tmrDelay_Tick(object sender, EventArgs e)
{
tmrDelay.Enabled = false;
switch (eMode)
{
case enuMode.warnPlayerNextTurn:
eMode = enuMode.beginTurn;
break;
case enuMode.animateMove:
moveStep();
break;
case enuMode.showAllowableMoves:
cSuspects[intSuspectTurn].endShowAllowableMoves();
break;
case enuMode.rollDie_animate:
rollDie_animate();
break;
case enuMode.animateIntroduction:
animateIntroduction();
break;
case enuMode.animateSummonSuspect:
animateSummonSuspect();
break;
case enuMode.animateSummonWeapon:
animateSummonWeapon();
break;
case enuMode.Accuse_Animation:
case enuMode.Accuse:
animateAccusation();
break;
case enuMode.animateSecretPassage:
AnimateSecretPassage();
break;
case enuMode.gameOver:
eMode = enuMode.animateIntroduction;
break;
case enuMode.idle:
case enuMode.dealCards:
animateDealCards();
break;
}
}
void cLibPicTraySuspectTmrRotate_Tick(object sender, EventArgs e)
{
switch (eMode)
{
case enuMode.Accuse:
setAccusation();
break;
case enuMode.Suggest:
setSuggestion();
break;
case enuMode.chooseCharacter:
setBtnChooseSuspectColorAndText();
break;
}
}
void cLibPicTrayWeaponTmrRotate_Tick(object sender, EventArgs e)
{
switch (eMode)
{
case enuMode.Accuse:
setAccusation();
break;
case enuMode.Suggest:
setSuggestion();
break;
}
}
#endregion
#region "animate intro"
enuIntroAnimationMode eIntroMode
{
get { return udrAniIntro.eMode; }
set
{
udrAniIntro.eMode = value;
udrAniIntro.bolInit = false;
}
}
void initAnimationIntroBehindTheLenseImages()
{
Bitmap bmpMegaBoard = new Bitmap(Clue_CS2010.Properties.Resources.Board_Under_Lense);
udrAniIntro.udrMagnifyingGlass.bmpLense = new Bitmap(Clue_CS2010.Properties.Resources.magnifying_glass);
udrAniIntro.udrMagnifyingGlass.bmpHandle = new Bitmap(Clue_CS2010.Properties.Resources.magnifying_handle);
udrAniIntro.udrMagnifyingGlass.bmpHandle.MakeTransparent(udrAniIntro.udrMagnifyingGlass.bmpHandle.GetPixel(0, 0));
int intMaxFitHorizontally = (int)(Math.Floor((double)bmpMegaBoard.Width / (2.0 * (double)Clue_CS2010.Properties.Resources.magnifying_glass.Width)));
int intMaxFitVertically = (int)(Math.Floor((double)bmpMegaBoard.Height / (2.0 * (double)Clue_CS2010.Properties.Resources.magnifying_glass.Height)));
udrAniIntro.udrBoardUnderLense.szArray = new System.Drawing.Size(2 * intMaxFitHorizontally - 1,
2 * intMaxFitVertically - 1);
udrAniIntro.udrBoardUnderLense.udrParcels =new udtIntro_Animation_BoardParcel[udrAniIntro.udrBoardUnderLense.szArray.Width, udrAniIntro.udrBoardUnderLense.szArray.Height];
udrAniIntro.udrBoardUnderLense.szParcels = new Size(bmpMegaBoard.Width / intMaxFitHorizontally, bmpMegaBoard.Height / intMaxFitVertically);
Rectangle recDest = new Rectangle(0, 0, udrAniIntro.udrBoardUnderLense.szParcels.Width, udrAniIntro.udrBoardUnderLense.szParcels.Height);
for (int intX = 0; intX < udrAniIntro.udrBoardUnderLense.szArray.Width; intX++)
{
for (int intY = 0; intY < udrAniIntro.udrBoardUnderLense.szArray.Height; intY++)
{
udrAniIntro.udrBoardUnderLense.udrParcels[intX, intY].bmp = new Bitmap(udrAniIntro.udrBoardUnderLense.szParcels.Width, udrAniIntro.udrBoardUnderLense.szParcels.Height);
udrAniIntro.udrBoardUnderLense.udrParcels[intX, intY].rec = new Rectangle(intX * udrAniIntro.udrBoardUnderLense.szParcels.Width / 2, intY * udrAniIntro.udrBoardUnderLense.szParcels.Height / 2, udrAniIntro.udrBoardUnderLense.szParcels.Width, udrAniIntro.udrBoardUnderLense.szParcels.Height);
using (Graphics g = Graphics.FromImage(udrAniIntro.udrBoardUnderLense.udrParcels[intX, intY].bmp))
g.DrawImage(bmpMegaBoard, recDest, udrAniIntro.udrBoardUnderLense.udrParcels[intX, intY].rec, GraphicsUnit.Pixel);
advanceProBar();
}
}
}
void initAnimateIntroduction()
{
//bolGameOver = false;
Bitmap bmpTemp = new Bitmap(bmpBoard.Width + bmpNotebook.Width +5, bmpBoard.Height);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.DrawImage(bmpBoard, new Point(0, 0));
g.DrawImage(bmpNotebook, new Point(bmpBoard.Width+5, 0));
Bitmap bmpLogo = new Bitmap(Clue_CS2010.Properties.Resources.clue_logo);
bmpLogo.MakeTransparent();
g.DrawImage(bmpLogo, (bmpTemp.Width - bmpLogo.Width) / 2, (bmpTemp.Height - bmpLogo.Height) / 2);
}
picBoard.Size = bmpTemp.Size;
picBoard.Image = bmpTemp;
picBoard.BringToFront();
udrAniIntro.bmpBoard = bmpTemp;
udrAniIntro.udrMagnifyingGlass.ptCenterLense = new Point(udrAniIntro.udrMagnifyingGlass.bmpLense.Width / 2, udrAniIntro.udrMagnifyingGlass.bmpLense.Height / 2);
udrAniIntro.udrMagnifyingGlass.clrBackground = udrAniIntro.udrMagnifyingGlass.bmpLense.GetPixel(0, 0);
udrAniIntro.udrMagnifyingGlass.clrLense = udrAniIntro.udrMagnifyingGlass.bmpLense.GetPixel(udrAniIntro.udrMagnifyingGlass.ptCenterLense.X, udrAniIntro.udrMagnifyingGlass.ptCenterLense.Y);
// initialize intro animation sprites
udrAniIntro.sprites = new udtIntro_Animation_Sprites[(int)enuIntroAnimationSprites._NumIntroAnimationSprites];
udrAniIntro.sprites[(int)enuIntroAnimationSprites.waldo].cSprite = spriteMaker.loadSprite(getSpriteFilename(enuIntroAnimationSprites.waldo.ToString()));
udrAniIntro.sprites[(int)enuIntroAnimationSprites.waldo].udrAniInfo.ptPos = new Point(336, 1784);
udrAniIntro.sprites[(int)enuIntroAnimationSprites.Jessica_Rabbit].cSprite = spriteMaker.loadSprite(getSpriteFilename(enuIntroAnimationSprites.Jessica_Rabbit.ToString()));
udrAniIntro.sprites[(int)enuIntroAnimationSprites.Jessica_Rabbit].udrAniInfo.ptPos = new Point(420, 708);
udrAniIntro.sprites[(int)enuIntroAnimationSprites.RatProtester].cSprite = spriteMaker.loadSprite(getSpriteFilename(enuIntroAnimationSprites.RatProtester.ToString()));
udrAniIntro.sprites[(int)enuIntroAnimationSprites.RatProtester].udrAniInfo.ptPos = new Point(1100, 418);
udrAniIntro.sprites[(int)enuIntroAnimationSprites.RatProtester].eMirror = Sprite.enuMirror.none;
eIntroMode = (enuIntroAnimationMode)0;
setDelayTimer(10);
}
string getSpriteFilename(string strFilename)
{
//if (bolDebug)
// return "c:\\sprites\\" + strFilename + "\\" + strFilename + ".sp2";
string strDirectory = System.IO.Directory.GetCurrentDirectory();
string strFilenameAndDirectory = strDirectory + "\\" + strFilename + ".sp2";
while (strFilenameAndDirectory.Length > 0 && !System.IO.File.Exists(strFilenameAndDirectory))
{
int intIndex = strDirectory.LastIndexOf("\\");
if (intIndex > 0)
{
strDirectory = strDirectory.Substring(0, intIndex);
strFilenameAndDirectory = strDirectory +"\\" + strFilename + ".sp2";
}
else
strFilenameAndDirectory = "";
}
return strFilenameAndDirectory;
}
void animateIntroduction()
{
if (!udrAniIntro.bolInit)
{
switch (udrAniIntro.eMode)
{
case enuIntroAnimationMode.moveToBawdyMansion:
udrAniIntro.udrMagnifyingGlass.ptStart = new Point(-550, 50);
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(1092, 60);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 8;
break;
case enuIntroAnimationMode.moveToRat:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(1119, 418);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 12;
break;
case enuIntroAnimationMode.movetoCKLovesVP:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(2740, 236);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 6;
break;
case enuIntroAnimationMode.moveToBritneyWasHere:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(2732, 1404);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 6;
break;
case enuIntroAnimationMode.moveToSpider:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(1904, 1687);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 3;
break;
case enuIntroAnimationMode.moveToCheese:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(2076, 2020);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 3;
break;
case enuIntroAnimationMode.moveToCat:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(1100, 2044);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 1;
break;
case enuIntroAnimationMode.moveToWaldo:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(336, 1784);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 15;
break;
case enuIntroAnimationMode.moveToJessicaRabbit:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(420, 738);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 15;
break;
case enuIntroAnimationMode.moveToWrittenBy:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(884, 952);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 5;
break;
case enuIntroAnimationMode.moveToChristKennedy:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(2299, 1265);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 20;
break;
case enuIntroAnimationMode.moveToYear:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(289, 1429);
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
udrAniIntro.udrMagnifyingGlass.intHoverMax = 4;
break;
case enuIntroAnimationMode.moveToEnd:
udrAniIntro.udrMagnifyingGlass.ptStart = udrAniIntro.udrMagnifyingGlass.ptPos;
udrAniIntro.udrMagnifyingGlass.ptEnd = new Point(-550, (Clue_CS2010.Properties.Resources.Board_Under_Lense.Height) - 50);
udrAniIntro.udrMagnifyingGlass.intHoverMax = 0;
udrAniIntro.udrMagnifyingGlass.intHoverStep = 0;
break;
}
udrAniIntro.udrMagnifyingGlass.intStep = 0;
udrAniIntro.udrMagnifyingGlass.dblTravelAngle = classMath.arcTan(udrAniIntro.udrMagnifyingGlass.ptEnd, udrAniIntro.udrMagnifyingGlass.ptStart);
udrAniIntro.udrMagnifyingGlass.dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniIntro.udrMagnifyingGlass.ptEnd, udrAniIntro.udrMagnifyingGlass.ptStart);
udrAniIntro.udrMagnifyingGlass.intMaxSteps = (int)(Math.Ceiling(udrAniIntro.udrMagnifyingGlass.dblTravelDistance / 60));
udrAniIntro.bolInit = true;
}
// animate sprites
for (enuIntroAnimationSprites eSpriteCounter = (enuIntroAnimationSprites)0; eSpriteCounter < enuIntroAnimationSprites._NumIntroAnimationSprites; eSpriteCounter++)
{
switch (eSpriteCounter)
{
case enuIntroAnimationSprites.RatProtester:
udrAniIntro.sprites[(int)eSpriteCounter].intConfigurationStep = (udrAniIntro.sprites[(int)eSpriteCounter].intConfigurationStep + 1) % udrAniIntro.sprites[(int)eSpriteCounter].cSprite.Configurations[udrAniIntro.sprites[(int)eSpriteCounter].intConfiguration].steps.Length;
if (udrAniIntro.sprites[(int)eSpriteCounter].intConfigurationStep == 0)
{
if (udrAniIntro.sprites[(int)eSpriteCounter].eMirror == Sprite.enuMirror.none)
udrAniIntro.sprites[(int)eSpriteCounter].eMirror = Sprite.enuMirror.horizontal;
else
udrAniIntro.sprites[(int)eSpriteCounter].eMirror = Sprite.enuMirror.none;
}
int intStepSize = 20;
udrAniIntro.sprites[(int)eSpriteCounter].udrAniInfo.ptPos.X += (udrAniIntro.sprites[(int)eSpriteCounter].eMirror == Sprite.enuMirror.none ? 1 : -1) * intStepSize;
break;
default:
udrAniIntro.sprites[(int)eSpriteCounter].intConfigurationStep = (udrAniIntro.sprites[(int)eSpriteCounter].intConfigurationStep + 1) % udrAniIntro.sprites[(int)eSpriteCounter].cSprite.Configurations[udrAniIntro.sprites[(int)eSpriteCounter].intConfiguration].steps.Length;
if (udrAniIntro.sprites[(int)eSpriteCounter].intConfigurationStep == 0)
udrAniIntro.sprites[(int)eSpriteCounter].intConfiguration = (int)(rnd.NextDouble() * 10000 * udrAniIntro.sprites[(int)eSpriteCounter].cSprite.Configurations.Length) % udrAniIntro.sprites[(int)eSpriteCounter].cSprite.Configurations.Length;
break;
}
}
// move magnifying glass over mega board
if (udrAniIntro.udrMagnifyingGlass.intStep < udrAniIntro.udrMagnifyingGlass.intMaxSteps)
{
udrAniIntro.udrMagnifyingGlass.intStep++;
double dblPercentDistanceTravelled = ((double)udrAniIntro.udrMagnifyingGlass.intStep / (double)udrAniIntro.udrMagnifyingGlass.intMaxSteps);
udrAniIntro.udrMagnifyingGlass.ptPos.X = (int)(udrAniIntro.udrMagnifyingGlass.ptStart.X + dblPercentDistanceTravelled * udrAniIntro.udrMagnifyingGlass.dblTravelDistance * Math.Cos(udrAniIntro.udrMagnifyingGlass.dblTravelAngle));
udrAniIntro.udrMagnifyingGlass.ptPos.Y = (int)(udrAniIntro.udrMagnifyingGlass.ptStart.Y + dblPercentDistanceTravelled * udrAniIntro.udrMagnifyingGlass.dblTravelDistance * Math.Sin(udrAniIntro.udrMagnifyingGlass.dblTravelAngle));
}
// create image of lense
Bitmap bmpTempLense = new Bitmap(udrAniIntro.udrMagnifyingGlass.bmpLense.Width, udrAniIntro.udrMagnifyingGlass.bmpLense.Height);
Rectangle recSrcMegaParcel;
Rectangle recDestMegaBoard = new Rectangle(0, 0, bmpTempLense.Width, bmpTempLense.Height);
Rectangle recSrcMegaBoard = new Rectangle(getMagnifyingLenseTLOnMegaBoard(udrAniIntro.udrMagnifyingGlass.ptPos), bmpTempLense.Size);
using (Graphics g = Graphics.FromImage(bmpTempLense))
{
// copy mega board image onto temp bmp
Point ptIndex = new Point(udrAniIntro.udrBoardUnderLense.szArray.Width - 1, udrAniIntro.udrBoardUnderLense.szArray.Height - 1);
while (ptIndex.X > 0 && udrAniIntro.udrBoardUnderLense.udrParcels[ptIndex.X, ptIndex.Y].rec.Left > recSrcMegaBoard.Left)
ptIndex.X--;
while (ptIndex.Y > 0 && udrAniIntro.udrBoardUnderLense.udrParcels[ptIndex.X, ptIndex.Y].rec.Top > recSrcMegaBoard.Top)
ptIndex.Y--;
recSrcMegaParcel = new Rectangle(recSrcMegaBoard.Left - udrAniIntro.udrBoardUnderLense.udrParcels[ptIndex.X, ptIndex.Y].rec.Left,
recSrcMegaBoard.Top - udrAniIntro.udrBoardUnderLense.udrParcels[ptIndex.X, ptIndex.Y].rec.Top,
recSrcMegaBoard.Width,
recSrcMegaBoard.Height);
g.DrawImage(udrAniIntro.udrBoardUnderLense.udrParcels[ptIndex.X, ptIndex.Y].bmp, recDestMegaBoard, recSrcMegaParcel, GraphicsUnit.Pixel);
Point ptLenseCenter = udrAniIntro.udrMagnifyingGlass.ptPos;
for (int intSpriteCounter = 0; intSpriteCounter < udrAniIntro.sprites.Length; intSpriteCounter++)
{
double dblDistance = classMath.distanceBetweenTwoPoints(ptLenseCenter, udrAniIntro.sprites[intSpriteCounter].udrAniInfo.ptPos);
if (dblDistance < 200)
{ // draw this sprite
Point ptSprite = new Point(udrAniIntro.sprites[intSpriteCounter].udrAniInfo.ptPos.X - recSrcMegaBoard.Left,
udrAniIntro.sprites[intSpriteCounter].udrAniInfo.ptPos.Y - recSrcMegaBoard.Top);
udrAniIntro.sprites[intSpriteCounter].cSprite.putConfigurationOnScreen(ref bmpTempLense,
udrAniIntro.sprites[intSpriteCounter].intConfiguration,
udrAniIntro.sprites[intSpriteCounter].intConfigurationStep,
ptSprite,
0,
1.0,
udrAniIntro.sprites[intSpriteCounter].eMirror,
false);
}
}
udrAniIntro.udrMagnifyingGlass.bmpLense.MakeTransparent(udrAniIntro.udrMagnifyingGlass.clrLense);
g.DrawImage(udrAniIntro.udrMagnifyingGlass.bmpLense, new Point(0, 0));
}
// make temp lense background transparent then draw onto regular board
bmpTempLense.MakeTransparent(udrAniIntro.udrMagnifyingGlass.clrBackground);
Bitmap bmpNewBoard = new Bitmap(udrAniIntro.bmpBoard);
using (Graphics g = Graphics.FromImage(bmpNewBoard))
{
Point ptTLLense = getMagnifyingLenseTLOnRegularBoard(udrAniIntro.udrMagnifyingGlass.ptPos);
g.DrawImage(bmpTempLense, ptTLLense);
g.DrawImage(udrAniIntro.udrMagnifyingGlass.bmpHandle, new Point(ptTLLense.X - 198, ptTLLense.Y + 229));
}
picBoard.Image = bmpNewBoard; picBoard.Refresh();
if (udrAniIntro.udrMagnifyingGlass.intStep >= udrAniIntro.udrMagnifyingGlass.intMaxSteps)
{
if (udrAniIntro.udrMagnifyingGlass.intHoverStep < udrAniIntro.udrMagnifyingGlass.intHoverMax)
{
udrAniIntro.udrMagnifyingGlass.intHoverStep++;
}
else
eIntroMode = (enuIntroAnimationMode)(((int)eIntroMode + 1) % (int)enuIntroAnimationMode._numIntroMode);
}
setDelayTimer(100);
}
Point getMagnifyingLenseTLOnRegularBoard(Point ptLenseCenterOnMegaBoard)
{
Point ptLenseCenterOnRegularBoard = new Point(ptLenseCenterOnMegaBoard.X / 3, ptLenseCenterOnMegaBoard.Y / 3);
return new Point(ptLenseCenterOnRegularBoard.X - udrAniIntro.udrMagnifyingGlass.ptCenterLense.X, ptLenseCenterOnRegularBoard.Y - udrAniIntro.udrMagnifyingGlass.ptCenterLense.Y);
}
Point getMagnifyingLenseTLOnMegaBoard(Point ptLenseCenterOnMegaBoard)
{
return new Point(ptLenseCenterOnMegaBoard.X - udrAniIntro.udrMagnifyingGlass.ptCenterLense.X, ptLenseCenterOnMegaBoard.Y - udrAniIntro.udrMagnifyingGlass.ptCenterLense.Y);
}
#endregion
#region "animate Deal Cards"
enuDealCardsMode eDealMode
{
get { return udrAnimateDealCards._eMode; }
set
{
int intHalfCardWidth = cCards[0].cBmp.getImage(0).Width / 2;
int intHalfCardHeight = cCards[0].cBmp.getImage(0).Height / 2;
if (udrAnimateDealCards._eMode != value)
{
udrAnimateDealCards._eMode = value;
// initialize animation for each mode
switch (eDealMode)
{
case enuDealCardsMode.SortCardsIntotypes:
udrAnimateDealCards.strCards = shuffleCards(false);
udrAnimateDealCards.intAnimationCounter = 0;
udrAnimateDealCards.cCardsCurrentAnimation = new classCard[0];
setDelayTimer(100);
break;
case enuDealCardsMode.gatherTypes:
udrAnimateDealCards.intAnimationCounter = 0;
break;
/// shuffle, select & hide weapons
case enuDealCardsMode.spreadWeaponCardsFaceUp:
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard_Base))
{
classCard cThisCard = udrAnimateDealCards.udrTypeOrder.cSuspects[udrAnimateDealCards.udrTypeOrder.cSuspects.Length - 1];
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - intHalfCardWidth, cThisCard.udrAnimationInfo.ptPos.Y - intHalfCardHeight);
g.DrawImage(cThisCard.cBmp.getImage(0), ptTL);
cThisCard = udrAnimateDealCards.udrTypeOrder.cRooms[udrAnimateDealCards.udrTypeOrder.cRooms.Length - 1];
ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - intHalfCardWidth, cThisCard.udrAnimationInfo.ptPos.Y - intHalfCardHeight);
g.DrawImage(cThisCard.cBmp.getImage(0), ptTL);
}
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.flipWeaponcards:
udrAnimateDealCards.bolInit = false;
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.shuffleWeaponCards:
udrAnimateDealCards.bolInit = false;
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.gatherFaceDownWeapons:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.spreadWeapondsCardsFaceDown:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.selectWeapon:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.gatherFaceDownWeapons_LessMurderWeapon:
udrAnimateDealCards.bolInit = false;
break;
/// shuffle, select & hide suspects
case enuDealCardsMode.spreadSuspectCardsFaceUp:
udrAnimateDealCards.intAnimationCounter = 0;
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard_Base))
{
// draw back weapon card stack
classCard cThisCard = udrAnimateDealCards.udrTypeOrder.cSuspects[udrAnimateDealCards.udrTypeOrder.cSuspects.Length - 1];
Point ptTL = new Point(ptAnimationTypeStackPos[(int)enuCardType.weapon].X - intHalfCardWidth, ptAnimationTypeStackPos[(int)enuCardType.weapon].Y - intHalfCardHeight);
g.DrawImage(cCardUnknown.cBmp.getImage(0), ptTL);
// draw front room stack
cThisCard = udrAnimateDealCards.udrTypeOrder.cRooms[udrAnimateDealCards.udrTypeOrder.cRooms.Length - 1];
ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - intHalfCardWidth, cThisCard.udrAnimationInfo.ptPos.Y - intHalfCardHeight);
g.DrawImage(cThisCard.cBmp.getImage(0), ptTL);
}
break;
case enuDealCardsMode.flipSuspectcards:
udrAnimateDealCards.bolInit = false;
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.shuffleSuspectCards:
udrAnimateDealCards.bolInit = false;
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.gatherFaceDownSuspects:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.spreadSuspectdsCardsFaceDown:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.selectSuspect:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.gatherFaceDownSuspects_LessMurderSuspect:
udrAnimateDealCards.bolInit = false;
break;
/// shuffle, select & hide Rooms
case enuDealCardsMode.spreadRoomCardsFaceUp:
udrAnimateDealCards.intAnimationCounter = 0;
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard_Base))
{
// draw back weapon card stack
Point ptTL = new Point(ptAnimationTypeStackPos[(int)enuCardType.weapon].X - intHalfCardWidth, ptAnimationTypeStackPos[(int)enuCardType.weapon].Y - intHalfCardHeight);
g.DrawImage(cCardUnknown.cBmp.getImage(0), ptTL);
// draw back suspect stack
ptTL = new Point(ptAnimationTypeStackPos[(int)enuCardType.Suspect].X - intHalfCardWidth, ptAnimationTypeStackPos[(int)enuCardType.Suspect].Y - intHalfCardHeight);
g.DrawImage(cCardUnknown.cBmp.getImage(0), ptTL);
}
break;
case enuDealCardsMode.flipRoomcards:
udrAnimateDealCards.bolInit = false;
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.shuffleRoomCards:
udrAnimateDealCards.bolInit = false;
udrAnimateDealCards.intAnimationCounter = 0;
break;
case enuDealCardsMode.gatherFaceDownRooms:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.spreadRoomdsCardsFaceDown:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.selectRoom:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.gatherFaceDownRooms_LessMurderRoom:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.shuffleCards:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.joinCardsAfterShuffle:
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.dealToPlayers:
udrAnimateDealCards.bolInit = false;
int intCardIndex = (int)classCard.getECardFromEWeapon(udrMurder.eWeapon);
cCards[intCardIndex].udrAnimationInfo.intStep = cCards[intCardIndex].udrAnimationInfo.intMaxSteps;
intCardIndex = (int)classCard.getECardFromERoom(udrMurder.eRoom);
cCards[intCardIndex].udrAnimationInfo.intStep = cCards[intCardIndex].udrAnimationInfo.intMaxSteps;
intCardIndex = (int)classCard.getECardFromESuspect(udrMurder.eSuspect);
cCards[intCardIndex].udrAnimationInfo.intStep = cCards[intCardIndex].udrAnimationInfo.intMaxSteps;
udrAnimateDealCards.strCards = strCardsDealt;
break;
case enuDealCardsMode.moveMurderCardsToCenter:
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
udrAnimateDealCards.cCardsCurrentAnimation = new classCard[3];
udrAnimateDealCards.cCardsCurrentAnimation[0] = cCards[(int)classCard.getECardFromESuspect ( udrMurder.eSuspect)];
udrAnimateDealCards.cCardsCurrentAnimation[1] = cCards[(int)classCard.getECardFromERoom ( udrMurder.eRoom)];
udrAnimateDealCards.cCardsCurrentAnimation[2] = cCards[(int)classCard.getECardFromEWeapon ( udrMurder.eWeapon)];
enuCards eWeapon = classCard.getECardFromEWeapon(udrMurder.eWeapon);
enuCards eSuspect = classCard.getECardFromESuspect(udrMurder.eSuspect);
enuCards eRoom = classCard.getECardFromERoom(udrMurder.eRoom);
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard_Base))
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
for (int intCardCounter = 0; intCardCounter < cSuspects[(int)eSuspectCounter].cCards.Length; intCardCounter++)
{
classCard cThisCard = cSuspects[(int)eSuspectCounter].cCards[intCardCounter];
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cThisCard.cSuspect.bolPlayerControlled ? cThisCard.cBmp.getImage(intImageIndex) : cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
cThisCard.udrAnimationInfo.intStep++;
}
}
udrAnimateDealCards.bolInit = false;
break;
case enuDealCardsMode.endDealCardsAnimation:
if (eMode == enuMode.idle)
{
eDealMode = enuDealCardsMode.SortCardsIntotypes;
return;
}
break;
}
}
}
}
Bitmap AnimateDealCards_getBlankDealCardsImage()
{
Bitmap bmpTemp = new Bitmap(pnlNotebook.Left + 240, picBoard.Height);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.DrawImage(bmpBoard, 0, 0);
g.DrawImage((Bitmap)Clue_CS2010.Properties.Resources.notebook, pnlNotebook.Left, 0);
}
return bmpTemp;
}
void animateDealCards()
{
if (udrAnimateDealCards.bolQuitAnimation)
{
if (eMode == enuMode.idle)
NewGame((object)this, new EventArgs());
else
eDealMode = enuDealCardsMode.endDealCardsAnimation;
}
switch (eDealMode)
{
case enuDealCardsMode.SortCardsIntotypes:
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
picBoard.Image = bmpDealAnimationBoard_Base;
picBoard.BringToFront();
AnimateDealCards_SortCardsIntoTypes();
break;
case enuDealCardsMode.gatherTypes:
AnimateDealCards_GatherTypes();
break;
/// shuffle, select & hide weapons
case enuDealCardsMode.spreadWeaponCardsFaceUp:
AnimateDealCards_SpreadCards(enuCardType.weapon, true);
break;
case enuDealCardsMode.flipWeaponcards:
AnimateDealCards_FlipCardsUtoD_DirR(enuCardType.weapon);
break;
case enuDealCardsMode.shuffleWeaponCards:
AnimateDealCards_Shuffle(enuCardType.weapon);
break;
case enuDealCardsMode.gatherFaceDownWeapons:
AnimateDealCards_GatherType(ptAnimationTypeStackPos[(int)enuCardType.weapon], enuCardType.weapon, false);
break;
case enuDealCardsMode.spreadWeapondsCardsFaceDown:
AnimateDealCards_SpreadCards(enuCardType.weapon, false);
break;
case enuDealCardsMode.selectWeapon:
AnimateDealCards_SelectCard(enuCardType.weapon);
break;
case enuDealCardsMode.gatherFaceDownWeapons_LessMurderWeapon:
AnimateDealCards_GatherType(ptAnimationTypeStackPos[(int)enuCardType.weapon], enuCardType.weapon, false);
break;
/// shuffle, select & hide Suspects
case enuDealCardsMode.spreadSuspectCardsFaceUp:
AnimateDealCards_SpreadCards(enuCardType.Suspect, true);
break;
case enuDealCardsMode.flipSuspectcards:
AnimateDealCards_FlipCardsUtoD_DirR(enuCardType.Suspect);
break;
case enuDealCardsMode.shuffleSuspectCards:
AnimateDealCards_Shuffle(enuCardType.Suspect);
break;
case enuDealCardsMode.gatherFaceDownSuspects:
AnimateDealCards_GatherType(ptAnimationTypeStackPos[(int)enuCardType.Suspect], enuCardType.Suspect, false);
break;
case enuDealCardsMode.spreadSuspectdsCardsFaceDown:
AnimateDealCards_SpreadCards(enuCardType.Suspect, false);
break;
case enuDealCardsMode.selectSuspect:
AnimateDealCards_SelectCard(enuCardType.Suspect);
break;
case enuDealCardsMode.gatherFaceDownSuspects_LessMurderSuspect:
AnimateDealCards_GatherType(ptAnimationTypeStackPos[(int)enuCardType.Suspect], enuCardType.Suspect, false);
break;
/// shuffle, select & hide Rooms
case enuDealCardsMode.spreadRoomCardsFaceUp:
AnimateDealCards_SpreadCards(enuCardType.room, true);
break;
case enuDealCardsMode.flipRoomcards:
AnimateDealCards_FlipCardsUtoD_DirR(enuCardType.room);
break;
case enuDealCardsMode.shuffleRoomCards:
AnimateDealCards_Shuffle(enuCardType.room);
break;
case enuDealCardsMode.gatherFaceDownRooms:
AnimateDealCards_GatherType(ptAnimationTypeStackPos[(int)enuCardType.room], enuCardType.room, false);
break;
case enuDealCardsMode.spreadRoomdsCardsFaceDown:
AnimateDealCards_SpreadCards(enuCardType.room, false);
break;
case enuDealCardsMode.selectRoom:
AnimateDealCards_SelectCard(enuCardType.room);
break;
case enuDealCardsMode.gatherFaceDownRooms_LessMurderRoom:
AnimateDealCards_GatherType(ptAnimationTypeStackPos[(int)enuCardType.room], enuCardType.room, false);
break;
case enuDealCardsMode.shuffleCards:
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
AnimateDealCards_ShuffleCards();
break;
case enuDealCardsMode.joinCardsAfterShuffle:
AnimateDealCards_JoinCards();
break;
case enuDealCardsMode.dealToPlayers:
AnimateDealCards_DealToPlayers();
break;
case enuDealCardsMode.moveMurderCardsToCenter:
AnimateDealCards_MoveMurderCardsToCenter();
break;
case enuDealCardsMode.endDealCardsAnimation:
if (eMode == enuMode.idle)
{
eDealMode = enuDealCardsMode.SortCardsIntotypes;
}
else
{
setPlayerNoteBook();
drawPlayerCards();
setSuspectsAI();
grbControls.Enabled = grbControls.Visible = true;
intSuspectTurn = 0;
eMode = enuMode.warnPlayerNextTurn;
}
break;
}
}
void AnimateDealCards_MoveMurderCardsToCenter()
{
if (!udrAnimateDealCards.bolInit)
{
udrAnimateDealCards.bolInit = true;
for (int intCardCounter = 0; intCardCounter < udrAnimateDealCards.cCardsCurrentAnimation.Length; intCardCounter++)
{
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[intCardCounter];
cThisCard.udrAnimationInfo.ptStart = getRoomCenter(enuRooms.Kitchen);
cThisCard.udrAnimationInfo.ptEnd = getRoomCenter(enuRooms._numRooms);
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.intMaxSteps = intCardCounter * 10 + 10;
cThisCard.udrAnimationInfo.intStep =0;
cThisCard.udrAnimationInfo.velTravel.X = (int)(cThisCard.udrAnimationInfo.dblTravelDistance / (double) cThisCard.udrAnimationInfo.intMaxSteps * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle));
cThisCard.udrAnimationInfo.velTravel.Y = (int)(cThisCard.udrAnimationInfo.dblTravelDistance / (double)cThisCard.udrAnimationInfo.intMaxSteps * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle));
double dblNumRotations = intCardCounter;
cThisCard.udrAnimationInfo.dblAngleTurning = (dblNumRotations * 2.0 * Math.PI) / (double)cThisCard.udrAnimationInfo.intMaxSteps * ((int)(rnd.NextDouble() * 1000) % 2 == 0 ? 1 : -1);
}
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
bool bolQuit = true;
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (int intCardCounter = 0; intCardCounter < udrAnimateDealCards.cCardsCurrentAnimation.Length; intCardCounter++)
{
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[intCardCounter];
if (cThisCard.udrAnimationInfo.intStep < cThisCard.udrAnimationInfo.intMaxSteps)
{
bolQuit = false;
// move this card along
cThisCard.udrAnimationInfo.ptPos.X += cThisCard.udrAnimationInfo.velTravel.X;
cThisCard.udrAnimationInfo.ptPos.Y += cThisCard.udrAnimationInfo.velTravel.Y;
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
}
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
cThisCard.udrAnimationInfo.intStep++;
if (cThisCard.udrAnimationInfo.intStep == cThisCard.udrAnimationInfo.intMaxSteps)
{
cThisCard.udrAnimationInfo.ptPos = cThisCard.udrAnimationInfo.ptEnd;
cThisCard.udrAnimationInfo.dblAngleFacing = 0;
}
}
}
picBoard.Image = bmpTemp; picBoard.Refresh();
if (bolQuit)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
}
setDelayTimer(10);
}
void AnimateDealCards_JoinCards()
{
enuCards eWeapon = classCard.getECardFromEWeapon(udrMurder.eWeapon);
enuCards eSuspect = classCard.getECardFromESuspect(udrMurder.eSuspect);
enuCards eRoom = classCard.getECardFromERoom(udrMurder.eRoom);
if (!udrAnimateDealCards.bolInit)
{
udrAnimateDealCards.bolInit = true;
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
classCard cThisCard = cCards[intCardCounter];
cThisCard.udrAnimationInfo.intMaxSteps = (int)(rnd.NextDouble() * 1000) % 15 + 10;
cThisCard.udrAnimationInfo.intStep = 0;
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd = getRoomCenter(enuRooms._numRooms);
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.velTravel.X = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle));
cThisCard.udrAnimationInfo.velTravel.Y = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle));
if (cThisCard.udrAnimationInfo.dblAngleFacing > Math.PI)
cThisCard.udrAnimationInfo.dblAngleTurning = (dblTwoPi - cThisCard.udrAnimationInfo.dblAngleFacing) / cThisCard.udrAnimationInfo.intMaxSteps;
else
cThisCard.udrAnimationInfo.dblAngleTurning = -cThisCard.udrAnimationInfo.dblAngleFacing / cThisCard.udrAnimationInfo.intMaxSteps;
if (Math.Abs(cThisCard.udrAnimationInfo.dblAngleTurning) < (Math.PI / 32.0))
{
cThisCard.udrAnimationInfo.dblAngleTurning = 0;
cThisCard.udrAnimationInfo.dblAngleFacing = 0;
}
}
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
bool bolQuit = true;
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
classCard cThisCard = cCards[intCardCounter];
if (cThisCard.eCardName != eWeapon
&& cThisCard.eCardName != eSuspect
&& cThisCard.eCardName != eRoom)
{
if (cThisCard.udrAnimationInfo.intStep < cThisCard.udrAnimationInfo.intMaxSteps)
{
bolQuit = false;
// move this card along
cThisCard.udrAnimationInfo.ptPos.X += cThisCard.udrAnimationInfo.velTravel.X;
cThisCard.udrAnimationInfo.ptPos.Y += cThisCard.udrAnimationInfo.velTravel.Y;
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
}
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing );
Bitmap bmp = cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
cThisCard.udrAnimationInfo.intStep++;
if (cThisCard.udrAnimationInfo.intStep == cThisCard.udrAnimationInfo.intMaxSteps)
{
cThisCard.udrAnimationInfo.ptPos = cThisCard.udrAnimationInfo.ptEnd;
cThisCard.udrAnimationInfo.dblAngleFacing = 0;
}
}
}
AnimateDealCards_drawMurderCards(g);
}
picBoard.Image = bmpTemp; picBoard.Refresh();
if (bolQuit)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
}
setDelayTimer(100);
}
int getImageIndex(double dblAngle) {return (int)(dblAngle/ (Math.PI / 8.0)) % 16; }
void AnimateDealCards_ShuffleCards()
{
if (!udrAnimateDealCards.bolInit)
{
udrAnimateDealCards.bolInit = true;
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
cCards[intCardCounter].udrAnimationInfo.intStep = cCards[intCardCounter].udrAnimationInfo.intMaxSteps;
cCards[intCardCounter].udrAnimationInfo.ptStart = cCards[intCardCounter].udrAnimationInfo.ptPos;
}
udrAnimateDealCards.udrShuffle.ptCentralShufflePos = getRoomCenter(enuRooms._numRooms);
udrAnimateDealCards.udrShuffle.intMaxDistance = (int)(bmpBoard.Width * .4);
udrAnimateDealCards.udrShuffle.intTimeShuffled = 0;
udrAnimateDealCards.udrShuffle.intMaxShuffle = 50;
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
enuCards eWeapon = classCard.getECardFromEWeapon(udrMurder.eWeapon);
enuCards eSuspect = classCard.getECardFromESuspect(udrMurder.eSuspect);
enuCards eRoom = classCard.getECardFromERoom(udrMurder.eRoom);
AnimateDealCards_drawMurderCards(g);
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
classCard cThisCard = cCards[intCardCounter];
if (cThisCard.eCardName != eWeapon
&& cThisCard.eCardName != eSuspect
&& cThisCard.eCardName != eRoom)
{
// prepare this card for next move
if (cThisCard.udrAnimationInfo.intStep >= cThisCard.udrAnimationInfo.intMaxSteps)
{
int intRndDistance = (int)(rnd.NextDouble() * 10000) % udrAnimateDealCards.udrShuffle.intMaxDistance;
double dblRndRad = rnd.NextDouble() * Math.PI * 2.0;
cThisCard.udrAnimationInfo.intMaxSteps = (int)(rnd.NextDouble() * 1000) % 5 + 5;
cThisCard.udrAnimationInfo.intStep = 0;
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd
= new Point(udrAnimateDealCards.udrShuffle.ptCentralShufflePos.X + (int)(intRndDistance * Math.Cos(dblRndRad)),
udrAnimateDealCards.udrShuffle.ptCentralShufflePos.Y + (int)(intRndDistance * Math.Sin(dblRndRad)));
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.velTravel.X = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle));
cThisCard.udrAnimationInfo.velTravel.Y = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle));
double dblMaxAngularVelocity = Math.PI * .2;
cThisCard.udrAnimationInfo.dblAngleTurning = rnd.NextDouble() * 2.0 * dblMaxAngularVelocity - dblMaxAngularVelocity;
}
// move this card along
cThisCard.udrAnimationInfo.ptPos.X += cThisCard.udrAnimationInfo.velTravel.X;
cThisCard.udrAnimationInfo.ptPos.Y += cThisCard.udrAnimationInfo.velTravel.Y;
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
cThisCard.udrAnimationInfo.intStep++;
}
}
}
picBoard.Image = bmpTemp; picBoard.Refresh();
udrAnimateDealCards.udrShuffle.intTimeShuffled++;
if (udrAnimateDealCards.udrShuffle.intTimeShuffled > udrAnimateDealCards.udrShuffle.intMaxShuffle)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
}
setDelayTimer(100);
}
void AnimateDealCards_DealToPlayers()
{
if (udrAnimateDealCards.intAnimationCounter % 8 == 0 && udrAnimateDealCards.strCards.Length > 0)
{
// throw new card across the table
int intNumCardsLeft = udrAnimateDealCards.strCards.Length / 2;
/// first card out is 6 + 6 + 9 = 21 - 3 = 18
enuSuspects eSuspectReceivingCard = (enuSuspects)((18 - intNumCardsLeft)%(int)enuSuspects._numSuspects);
string strThisCard = udrAnimateDealCards.strCards.Substring(0, 2);
udrAnimateDealCards.strCards = udrAnimateDealCards.strCards.Substring(2);
enuCards eCard = (enuCards)Convert.ToInt16(strThisCard);
Array.Resize<classCard>(ref udrAnimateDealCards.cCardsCurrentAnimation, udrAnimateDealCards.cCardsCurrentAnimation.Length + 1);
udrAnimateDealCards.cCardsCurrentAnimation[udrAnimateDealCards.cCardsCurrentAnimation.Length - 1] = cCards[(int)eCard];
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[udrAnimateDealCards.cCardsCurrentAnimation.Length - 1];
cSuspects[(int)eSuspectReceivingCard].receiveCard(ref cThisCard);
Point ptEnd = new Point(1, 1);
int intEdge = 20;
switch (eSuspectReceivingCard)
{
case enuSuspects.MissScarlet:
ptEnd = new Point((int)(bmpBoard.Width * .6), intEdge );
break;
case enuSuspects.ColMustard:
ptEnd = new Point((int)(bmpBoard.Width - intEdge ), (int)(bmpBoard.Height *.3));
break;
case enuSuspects.MrsWhite:
ptEnd = new Point((int)(bmpBoard.Width *.7 ), (int)(bmpBoard.Height - intEdge));
break;
case enuSuspects.RevGreen:
ptEnd = new Point((int)(bmpBoard.Width * .3), (int)(bmpBoard.Height - intEdge));
break;
case enuSuspects.MrsPeacock:
ptEnd = new Point(intEdge, (int)(bmpBoard.Height *.7));
break;
case enuSuspects.ProfPlum:
ptEnd = new Point(intEdge, (int)(bmpBoard.Height * .3));
break;
}
cThisCard.cSuspect = cSuspects[(int)eSuspectReceivingCard];
int intRangeError = (int)(bmpBoard.Height * .04);
ptEnd = new Point((int)(ptEnd.X + (int)(rnd.NextDouble() * 1000) % intRangeError * Math.Cos(rnd.NextDouble() * Math.PI * 2)),
(int)(ptEnd.Y + (int)(rnd.NextDouble() * 1000) % intRangeError * Math.Sin(rnd.NextDouble() * Math.PI * 2)));
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd = ptEnd;
cThisCard.udrAnimationInfo.dblTravelAcceleration = -5;
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.intMaxSteps = (int)Math.Ceiling(Math.Sqrt(-2.0 * cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.dblTravelAcceleration));
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = -cThisCard.udrAnimationInfo.dblTravelAcceleration * cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblAngleTurning = rnd.NextDouble() * Math.PI * (1.0 / 8.0);
cThisCard.udrAnimationInfo.intStep = 0;
cThisCard.udrAnimationInfo.dblAngleTurningAttenuation = 0.95;
}
udrAnimateDealCards.intAnimationCounter++;
bmpDealAnimationBoard = new Bitmap(bmpDealAnimationBoard_Base);
bool bolEndSortCards = true;
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard))
{
if (udrAnimateDealCards.strCards.Length > 0)
{ // if there are still cards left in the center stack -> draw center stack
Bitmap bmp = cCardUnknown.cBmp.getImage(0);
Point ptTL = new Point(getRoomCenter(enuRooms._numRooms).X - bmp.Width / 2, getRoomCenter(enuRooms._numRooms).Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
}
// draw murder cards
Bitmap bmpMurderCards = cCardUnknown.cBmp.getImage(0);
Point ptTLMurderCards = new Point(getRoomCenter(enuRooms.Kitchen).X - bmpMurderCards.Width / 2, getRoomCenter(enuRooms.Kitchen).Y - bmpMurderCards.Height / 2);
g.DrawImage(bmpMurderCards, ptTLMurderCards);
for (int intCardCounter = 0; intCardCounter < udrAnimateDealCards.cCardsCurrentAnimation.Length; intCardCounter++)
{
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[intCardCounter];
if (cThisCard.udrAnimationInfo.intStep < cThisCard.udrAnimationInfo.intMaxSteps)
{
bolEndSortCards = false;
cThisCard.udrAnimationInfo.intStep++;
double dblDistanceTravelled = cThisCard.udrAnimationInfo.dblTravelInitialVelocity * cThisCard.udrAnimationInfo.intStep + .5 * cThisCard.udrAnimationInfo.dblTravelAcceleration * cThisCard.udrAnimationInfo.intStep * cThisCard.udrAnimationInfo.intStep;
cThisCard.udrAnimationInfo.ptPos = new Point(cThisCard.udrAnimationInfo.ptStart.X + (int)(dblDistanceTravelled * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle)),
cThisCard.udrAnimationInfo.ptStart.Y + (int)(dblDistanceTravelled * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle)));
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
cThisCard.udrAnimationInfo.dblAngleTurning *= cThisCard.udrAnimationInfo.dblAngleTurningAttenuation;
}
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cThisCard.cSuspect.bolPlayerControlled ? cThisCard.cBmp.getImage (intImageIndex): cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
}
}
picBoard.Image = bmpDealAnimationBoard; picBoard.Refresh();
if (bolEndSortCards && udrAnimateDealCards.strCards.Length == 0)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
udrAnimateDealCards.intAnimationCounter = 0;
}
setDelayTimer(10);
}
void AnimateDealCards_SelectCard(enuCardType eTypeCard)
{
classCard cThisCard = cCards[(int)classCard.getECardFromERoom(udrMurder.eRoom)];
classCard[] cCardsArray = udrAnimateDealCards.udrTypeOrder.cRooms;
switch (eTypeCard)
{
case enuCardType.Suspect:
cCardsArray = udrAnimateDealCards.udrTypeOrder.cSuspects;
cThisCard = cCards[(int)classCard.getECardFromESuspect(udrMurder.eSuspect)];
break;
case enuCardType.weapon:
cCardsArray = udrAnimateDealCards.udrTypeOrder.cWeapons;
cThisCard = cCards[(int)classCard.getECardFromEWeapon(udrMurder.eWeapon)];
break;
}
if (!udrAnimateDealCards.bolInit)
{
for (int intCardCounter = 0; intCardCounter < cCardsArray.Length; intCardCounter++)
{
cCardsArray[intCardCounter].udrAnimationInfo.ptStart = cCardsArray[intCardCounter].udrAnimationInfo.ptPos;
cCardsArray[intCardCounter].udrAnimationInfo.ptEnd = cCardsArray[intCardCounter].udrAnimationInfo.ptPos;
cCardsArray[intCardCounter].udrAnimationInfo.dblAngleFacing = 0;
}
udrAnimateDealCards.bolInit = true;
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd = getRoomCenter(enuRooms.Kitchen);
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.intMaxSteps = (int)(cThisCard.udrAnimationInfo.dblTravelDistance / 40);
cThisCard.udrAnimationInfo.intStep = 0;
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.velTravel.X = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle));
cThisCard.udrAnimationInfo.velTravel.Y = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle));
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
if (eDealMode > enuDealCardsMode.selectWeapon)
AnimateDealCards_drawMurderCards(g);
// move this card along
cThisCard.udrAnimationInfo.ptPos.X += cThisCard.udrAnimationInfo.velTravel.X;
cThisCard.udrAnimationInfo.ptPos.Y += cThisCard.udrAnimationInfo.velTravel.Y;
cThisCard.udrAnimationInfo.intStep++;
for (int intCardCounter = 0; intCardCounter < cCardsArray.Length; intCardCounter++)
{
int intImageIndex = getImageIndex(cCardsArray[intCardCounter].udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cCardsArray[intCardCounter].udrAnimationInfo.ptPos.X - bmp.Width / 2, cCardsArray[intCardCounter].udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
}
}
picBoard.Image = bmpTemp; picBoard.Refresh();
if (cThisCard.udrAnimationInfo.intStep >= cThisCard.udrAnimationInfo.intMaxSteps)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
}
setDelayTimer(10);
}
void AnimateDealCards_drawMurderCards(Graphics g)
{
Point ptKitchen = getRoomCenter(enuRooms.Kitchen);
Bitmap bmpCard = cCardUnknown.cBmp.getImage(0);
Point ptTL = new Point(ptKitchen.X - bmpCard.Width / 2, ptKitchen.Y - bmpCard.Height / 2);
g.DrawImage(bmpCard, ptTL);
}
void AnimateDealCards_Shuffle(enuCardType eTypeCard)
{
if (!udrAnimateDealCards.bolInit)
{
udrAnimateDealCards.bolInit = true;
udrAnimateDealCards.intAnimationCounter = 0;
classCard[] cCardsInitArray = udrAnimateDealCards.udrTypeOrder.cRooms;
switch (eTypeCard)
{
case enuCardType.Suspect:
cCardsInitArray = udrAnimateDealCards.udrTypeOrder.cSuspects;
break;
case enuCardType.weapon:
cCardsInitArray = udrAnimateDealCards.udrTypeOrder.cWeapons;
break;
}
for (int intCardCounter = 0; intCardCounter < cCardsInitArray.Length; intCardCounter++)
{
cCardsInitArray[intCardCounter].udrAnimationInfo.intStep = cCardsInitArray[intCardCounter].udrAnimationInfo.intMaxSteps;
cCardsInitArray[intCardCounter].udrAnimationInfo.ptStart = cCardsInitArray[intCardCounter].udrAnimationInfo.ptPos;
cCardsInitArray[intCardCounter].udrAnimationInfo.dblAngleFacing = 0;
}
udrAnimateDealCards.udrShuffle.ptCentralShufflePos = cCardsInitArray[cCardsInitArray.Length / 2].udrAnimationInfo.ptPos;
udrAnimateDealCards.udrShuffle.intMaxDistance = (int)(bmpBoard.Width * .3);
udrAnimateDealCards.udrShuffle.intTimeShuffled = 0;
udrAnimateDealCards.udrShuffle.intMaxShuffle = 40;
}
classCard[] cCardsArray = udrAnimateDealCards.udrTypeOrder.cRooms;
switch (eTypeCard)
{
case enuCardType.Suspect:
cCardsArray = udrAnimateDealCards.udrTypeOrder.cSuspects;
break;
case enuCardType.weapon:
cCardsArray = udrAnimateDealCards.udrTypeOrder.cWeapons;
break;
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
if (eDealMode > enuDealCardsMode.selectWeapon)
AnimateDealCards_drawMurderCards(g);
for (int intCardCounter = 0; intCardCounter < cCardsArray.Length; intCardCounter++)
{
classCard cThisCard = cCardsArray[intCardCounter];
// prepare this card for next move
if (cThisCard.udrAnimationInfo.intStep >= cThisCard.udrAnimationInfo.intMaxSteps)
{
int intRndDistance = (int)(rnd.NextDouble() * 10000) % udrAnimateDealCards.udrShuffle.intMaxDistance;
double dblRndRad = rnd.NextDouble() * Math.PI * 2.0;
cThisCard.udrAnimationInfo.intMaxSteps = (int)(rnd.NextDouble() * 1000) % 10 + 5;
cThisCard.udrAnimationInfo.intStep = 0;
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd
= new Point(udrAnimateDealCards.udrShuffle.ptCentralShufflePos.X + (int)(intRndDistance * Math.Cos(dblRndRad)),
udrAnimateDealCards.udrShuffle.ptCentralShufflePos.Y + (int)(intRndDistance * Math.Sin(dblRndRad)));
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.velTravel.X = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle));
cThisCard.udrAnimationInfo.velTravel.Y = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle));
double dblMaxAngularVelocity = Math.PI * .02;
cThisCard.udrAnimationInfo.dblAngleTurning = rnd.NextDouble() * 2.0 * dblMaxAngularVelocity - dblMaxAngularVelocity;
cThisCard.udrAnimationInfo.dblAngleFacing = 0;
}
// move this card along
cThisCard.udrAnimationInfo.ptPos.X += cThisCard.udrAnimationInfo.velTravel.X;
cThisCard.udrAnimationInfo.ptPos.Y += cThisCard.udrAnimationInfo.velTravel.Y;
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
cThisCard.udrAnimationInfo.intStep++;
}
}
picBoard.Image = bmpTemp; picBoard.Refresh();
// randomly swap two cards
if (udrAnimateDealCards.udrShuffle.intTimeShuffled > 10)
{
int intRndA = 0, intRndB = 0;
while (intRndA == intRndB)
{
intRndB = (int)(rnd.NextDouble() * 1000) % cCardsArray.Length;
intRndA = (int)(rnd.NextDouble() * 1000) % cCardsArray.Length;
}
classCard cTemp = cCardsArray[intRndA];
cCardsArray[intRndA] = cCardsArray[intRndB];
cCardsArray[intRndB] = cTemp;
}
udrAnimateDealCards.udrShuffle.intTimeShuffled++;
if (udrAnimateDealCards.udrShuffle.intTimeShuffled > udrAnimateDealCards.udrShuffle.intMaxShuffle)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
}
setDelayTimer(10);
}
void AnimateDealCards_GatherType(Point ptDestination, enuCardType eCardType, bool bolFaceUp)
{
classCard[] cCardsArray = udrAnimateDealCards.udrTypeOrder.cRooms;
classCard cCardException = null;
switch (eCardType)
{
case enuCardType.room:
if (eDealMode > enuDealCardsMode.selectRoom)
cCardException = cCards[(int)classCard.getECardFromERoom(udrMurder.eRoom)];
break;
case enuCardType.Suspect:
cCardsArray = udrAnimateDealCards.udrTypeOrder.cSuspects;
if (eDealMode > enuDealCardsMode.selectSuspect)
cCardException = cCards[(int)classCard.getECardFromESuspect(udrMurder.eSuspect)];
break;
case enuCardType.weapon:
cCardsArray = udrAnimateDealCards.udrTypeOrder.cWeapons;
if (eDealMode > enuDealCardsMode.selectWeapon)
cCardException = cCards[(int)classCard.getECardFromEWeapon(udrMurder.eWeapon)];
break;
}
if (!udrAnimateDealCards.bolInit)
{
udrAnimateDealCards.bolInit = true;
for (int intCardCounter = 0; intCardCounter < cCardsArray.Length; intCardCounter++)
{
classCard cThisCard = cCardsArray[intCardCounter];
if (cThisCard != cCardException)
{
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd = ptDestination;
int intMaxSteps = (int)(rnd.NextDouble() * 1000) % 7 + 7;
cThisCard.udrAnimationInfo.intMaxSteps = intMaxSteps;
cThisCard.udrAnimationInfo.intStep = 0;
if (cThisCard.udrAnimationInfo.dblAngleFacing > Math.PI)
cThisCard.udrAnimationInfo.dblAngleTurning = (dblTwoPi - cThisCard.udrAnimationInfo.dblAngleFacing) / cThisCard.udrAnimationInfo.intMaxSteps;
else
cThisCard.udrAnimationInfo.dblAngleTurning = -cThisCard.udrAnimationInfo.dblAngleFacing / cThisCard.udrAnimationInfo.intMaxSteps;
if (Math.Abs(cThisCard.udrAnimationInfo.dblAngleTurning) < (Math.PI / 32.0))
{
cThisCard.udrAnimationInfo.dblAngleTurning = 0;
cThisCard.udrAnimationInfo.dblAngleFacing = 0;
}
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.velTravel.X = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle));
cThisCard.udrAnimationInfo.velTravel.Y = (int)(cThisCard.udrAnimationInfo.dblTravelInitialVelocity * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle));
}
}
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
bool bolQuit = true;
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (int intCardCounter = 0; intCardCounter < cCardsArray.Length; intCardCounter++)
{
classCard cThisCard = cCardsArray[intCardCounter];
if (cThisCard != cCardException)
{
cThisCard.udrAnimationInfo.ptPos.X += cThisCard.udrAnimationInfo.velTravel.X;
cThisCard.udrAnimationInfo.ptPos.Y += cThisCard.udrAnimationInfo.velTravel.Y;
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
cThisCard.udrAnimationInfo.intStep++;
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
if (cThisCard.udrAnimationInfo.intStep >= cThisCard.udrAnimationInfo.intMaxSteps)
{
cThisCard.udrAnimationInfo.ptPos = cThisCard.udrAnimationInfo.ptEnd;
intImageIndex = 0;
}
else
bolQuit = false;
Bitmap bmp = cThisCard.cBmp.getImage(intImageIndex);
if (!bolFaceUp)
bmp = cCardUnknown.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
}
}
if (eDealMode > enuDealCardsMode.selectWeapon)
AnimateDealCards_drawMurderCards(g);
}
picBoard.Image = bmpTemp; picBoard.Refresh();
if (bolQuit)
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
setDelayTimer(100);
}
/// <summary>
/// flip the weapon cards from a face up state to a face down one, moving from left-to-right
/// </summary>
void AnimateDealCards_FlipCardsUtoD_DirR(enuCardType eTypeCard)
{
classCard[] cAnimate = udrAnimateDealCards.udrTypeOrder.cRooms;
switch (eTypeCard)
{
case enuCardType.Suspect:
cAnimate = udrAnimateDealCards.udrTypeOrder.cSuspects;
break;
case enuCardType.weapon:
cAnimate = udrAnimateDealCards.udrTypeOrder.cWeapons;
break;
}
int intHalfCardWidth = cCards[0].cBmp.getImage(0).Width / 2;
int intCardHeight = cCards[0].cBmp.getImage(0).Height;
double dblCardWidth = cCards[0].cBmp.getImage(0).Width;
double dblK = 0;
if (!udrAnimateDealCards.bolInit)
{
for (int intCardCounter = 0; intCardCounter < cAnimate.Length; intCardCounter++)
{
classCard cThisCard = cAnimate[intCardCounter];
// record the edge of the card which remains in contact with the table in ptStart
cThisCard.udrAnimationInfo.ptStart = new Point(cThisCard.udrAnimationInfo.ptPos.X + intHalfCardWidth, cThisCard.udrAnimationInfo.ptPos.Y);
cThisCard.udrAnimationInfo.ptEnd = new Point(cThisCard.udrAnimationInfo.ptStart.X + cThisCard.cBmp.getImage(0).Width, cThisCard.udrAnimationInfo.ptStart.Y);
}
udrAnimateDealCards.intAnimationCounter = 0;
udrAnimateDealCards.bolInit = true;
setDelayTimer(100);
return;
}
int intMaxSteps = 30;
udrAnimateDealCards.intAnimationCounter++;
if (udrAnimateDealCards.intAnimationCounter >= intMaxSteps)
{
for (int intCardCounter = 0; intCardCounter < cAnimate.Length; intCardCounter++)
{
classCard cThisCard = cAnimate[intCardCounter];
// record the edge of the card which remains in contact with the table in ptStart
cThisCard.udrAnimationInfo.ptPos.X += (int)dblCardWidth;
}
udrAnimateDealCards.intAnimationCounter = 0;
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
setDelayTimer(100);
return;
}
double dblTotalDistance = 2 * dblCardWidth + cAnimate[cAnimate.Length - 1].udrAnimationInfo.ptStart.X - cAnimate[0].udrAnimationInfo.ptStart.X;
double dblMPivot = 0;
int intPivotPoint = (int)(((double)(udrAnimateDealCards.intAnimationCounter) / (double)(intMaxSteps)) * dblTotalDistance);
int intLeftMostPoint = cAnimate[0].udrAnimationInfo.ptStart.X - (int)dblCardWidth;
int intPivotCardIndex = cAnimate.Length;
Point ptTLImage;
Point ptTLPivotCard = new Point(0, 0);
// select Pivot Card
for (int intCardCounter = 0; intCardCounter < cAnimate.Length; intCardCounter++)
{
if (intLeftMostPoint + intPivotPoint < cAnimate[intCardCounter].udrAnimationInfo.ptStart.X)
{
intPivotCardIndex = intCardCounter;
break;
}
}
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
if (intPivotCardIndex < cAnimate.Length)
{
// calculate size and draw location of pivot card
int intLeftPivotCard = intPivotPoint;
classCard cPivotCard = cAnimate[intPivotCardIndex];
int intRightPivotCard = cPivotCard.udrAnimationInfo.ptStart.X;
ptTLImage = new Point(intLeftPivotCard + intLeftMostPoint, cPivotCard.udrAnimationInfo.ptPos.Y - cPivotCard.cBmp.getImage(0).Height / 2);
int intImageWidth = cPivotCard.udrAnimationInfo.ptStart.X - ptTLImage.X;
Bitmap bmpPivotCard = new Bitmap(cPivotCard.cBmp.getImage(0), intImageWidth, intCardHeight);
g.DrawImage(bmpPivotCard, ptTLImage);
if (intPivotCardIndex < cAnimate.Length - 1)
{
// calculate contact point with card to the right
/// view cards side-ways for calculations
/// form two lines of bottom edge of pivot card and card to the right of it (pivot cards leans towards the left w/ right-neighbor card pressed onto it)
/// where card to the right is leaning on pivot card
/// both lines are of equal lengths and share a common fixed y-value for their lowest points(table)
/// TL point of pivot card must be calculated given width of card (hypotenuse) & width of image (distance on x-plane away from pivot card's base point)
/// set common Y value = 0(table top)
/// set pivot card's known base point x value = 0(pivot card is in contact with that table in the system's origin)
/// forming a right-angle triangle with X-axis, Card's edge & imaginary vertical line
/// TL point of pivot card can be found
/// c^2 = a^2 + b^2 -> a = sqrt(c^2-b^2),
/// here Y point of TL is sqrt(CardWidth^2 - CardImageWidth^2)
/// and X point of TL is -CardImageWidth
ptTLPivotCard = new Point(-bmpPivotCard.Width, (int)Math.Sqrt(Math.Pow(dblCardWidth, 2) - Math.Pow(bmpPivotCard.Width, 2)));
dblMPivot = (double)ptTLPivotCard.Y / (double)ptTLPivotCard.X;
/// using the line equation y = Mx + B for both lines
/// we can calculate the point where both lines are in contact (x, y)
/// by using the two line equations separately
/// y = M1x + B1 and also y = M2x + B2
/// where (x,y) is common to both lines
/// we can drop an imaginary vertical line and form a right-angled triangle
/// knowing the hypotenuse is equal to C = card width
/// and the adjacent side alone the x-axis = (x - k) where K is the distance between cards
/// then solving the pythagorean triangle C^2 = A^2 + B^2 = (x-k)^2 + y^2 for y
/// we get y = sqrt(c^2 + 2xk - x^2 -k^2)
/// y = M1x + B1
/// putting these two equations together gives us the quadratic
/// x^2(M1^2 + 1) + x(-2k) + (K^2 - C^2) = 0
// constant distance between cards K
Point ptTLPreviousCard = ptTLPivotCard;
// calculate size and draw locations of all cards to the right of pivot card
for (int intCardCounter = intPivotCardIndex + 1; intCardCounter < cAnimate.Length; intCardCounter++)
{
classCard cThisCard = cAnimate[intCardCounter];
// solve for slope of pivot-card = dY/dX
double dblM1 = (double)ptTLPreviousCard.Y / (double)ptTLPreviousCard.X;
dblK = (cAnimate[intCardCounter].udrAnimationInfo.ptStart.X - cAnimate[intCardCounter - 1].udrAnimationInfo.ptStart.X);
// variables of quadratic equation
double dbl_A = (dblM1 * dblM1 + 1.0);
double dbl_B = -2 * dblK;
double dbl_C = dblK * dblK - dblCardWidth * dblCardWidth;
double dblX_Plus = (-dbl_B + Math.Sqrt(dbl_B * dbl_B - 4 * dbl_A * dbl_C)) / (2 * dbl_A);
double dblX_Minus = (-dbl_B - Math.Sqrt(dbl_B * dbl_B - 4 * dbl_A * dbl_C)) / (2 * dbl_A);
Point ptCommon = new Point(0, 0);
int intWidthImage = (int)dblCardWidth;
if (dblX_Minus > ptTLPreviousCard.X - 1 && dblX_Minus < 0)
{
double dblX = dblX_Minus - dblK;
ptCommon = new Point((int)dblX, (int)(dblX_Minus * dblM1));
intWidthImage = (int)(dblK - dblX_Minus);
}
else if (dblX_Plus > ptTLPreviousCard.X - 1 && dblX_Plus < 0)
{
double dblX = dblX_Plus - dblK;
ptCommon = new Point((int)dblX, (int)(dblX_Plus * dblM1));
intWidthImage = (int)(dblK - dblX_Plus);
}
else
{
ptCommon = new Point(cThisCard.udrAnimationInfo.ptStart.X - (int)dblCardWidth, 0);
}
/// previous card's base edge (ptStart.x + intHalfCard) is on the origin
if (ptCommon.X == 0)
ptCommon.X = 1;
Bitmap bmpThisCardImage = new Bitmap(cThisCard.cBmp.getImage(0), intWidthImage, intCardHeight);
ptTLImage = new Point(cThisCard.udrAnimationInfo.ptStart.X - intWidthImage, cThisCard.udrAnimationInfo.ptStart.Y - intCardHeight / 2);
g.DrawImage(bmpThisCardImage, ptTLImage);
ptTLPreviousCard = ptCommon;
}
}
}
if (intPivotCardIndex > 0)
{ // calculate size and draw locations of all cards to the left of pivot card
Point ptTRPreviousCard = new Point(0, 0);
Bitmap bmpCardUnknown;
int intWidthImage;
for (int intCardCounter = intPivotCardIndex - 1; intCardCounter >= 0; intCardCounter--)
{
classCard cThisCard = cAnimate[intCardCounter];
if (intCardCounter == cAnimate.Length - 1)
{
// all cards are faced down -> use Pivot point as x of TR corner for this right-most card
intWidthImage = intLeftMostPoint + intPivotPoint - (cThisCard.udrAnimationInfo.ptStart.X);
ptTLImage = new Point(cThisCard.udrAnimationInfo.ptStart.X, cThisCard.udrAnimationInfo.ptStart.Y - intCardHeight / 2);
bmpCardUnknown = new Bitmap(bmpCardBack, intWidthImage, intCardHeight);
g.DrawImage(bmpCardUnknown, ptTLImage);
ptTRPreviousCard = new Point(bmpCardUnknown.Width, (int)Math.Sqrt(Math.Pow(dblCardWidth, 2) - Math.Pow(bmpCardUnknown.Width, 2)));
}
else if (intCardCounter == intPivotCardIndex - 1)
{ // one or more cards are face down and this is the first card to the left of the pivot card
dblK = (cAnimate[intCardCounter + 1].udrAnimationInfo.ptStart.X - cAnimate[intCardCounter].udrAnimationInfo.ptStart.X);
intWidthImage = intLeftMostPoint + intPivotPoint - cAnimate[intCardCounter].udrAnimationInfo.ptStart.X;
ptTRPreviousCard = new Point(intWidthImage,
(int)(Math.Sqrt(dblCardWidth * dblCardWidth - intWidthImage * intWidthImage)));
ptTLImage = new Point(cThisCard.udrAnimationInfo.ptStart.X, cThisCard.udrAnimationInfo.ptStart.Y - intCardHeight / 2);
if (intWidthImage == 0)
{
intWidthImage = 1;
ptTRPreviousCard.X = 1;
}
bmpCardUnknown = new Bitmap(bmpCardBack, intWidthImage, intCardHeight);
g.DrawImage(bmpCardUnknown, ptTLImage);
}
else
{
dblK = (cAnimate[intCardCounter + 1].udrAnimationInfo.ptStart.X - cAnimate[intCardCounter].udrAnimationInfo.ptStart.X);
// this is one of the cards to the left of the pivot card
// calculate slope of the card on which this card is leaning
double dblM1 = (double)ptTRPreviousCard.Y / (double)ptTRPreviousCard.X;
/// we know the TR point of the previous card
/// both this card and card to the right lean towards the right with this card falling onto its right-neaghbor
/// drop an imaginary line from the point of contact(x,y) to form a right-angle triangle
/// using the previous card's base point as the origin
/// solve for y, set equal to y = M1x eq'n, drop the y's
/// get identical quadratic as previous case above
// variables of quadratic equation
double dbl_A = (dblM1 * dblM1 + 1);
double dbl_B = 2 * dblK;
double dbl_C = dblK * dblK - dblCardWidth * dblCardWidth;
double dblX_Plus = (-dbl_B + Math.Sqrt(dbl_B * dbl_B - 4 * dbl_A * dbl_C)) / (2 * dbl_A);
double dblX_Minus = (-dbl_B - Math.Sqrt(dbl_B * dbl_B - 4 * dbl_A * dbl_C)) / (2 * dbl_A);
int intImageWidth = (int)dblCardWidth;
if (dblX_Plus > 0 && dblX_Plus < ptTRPreviousCard.X)
{
intImageWidth = (int)(dblX_Plus + dblK);
ptTRPreviousCard = new Point((int)(dblK - dblX_Plus), (int)(dblM1 * (double)dblX_Plus));
}
else if (dblX_Minus > 0 && dblX_Minus < ptTRPreviousCard.X)
{
intImageWidth = (int)(dblX_Minus + dblK);
ptTRPreviousCard = new Point((int)(dblK - dblX_Plus), (int)(dblM1 * (double)dblX_Plus));
}
else
{
ptTRPreviousCard = new Point(cThisCard.udrAnimationInfo.ptStart.X + (int)dblCardWidth, 0);
}
ptTLImage = new Point(cThisCard.udrAnimationInfo.ptStart.X, cThisCard.udrAnimationInfo.ptStart.Y - intCardHeight / 2);
bmpCardUnknown = new Bitmap(bmpCardBack, intImageWidth, intCardHeight);
g.DrawImage(bmpCardUnknown, ptTLImage);
}
}
}
if (eDealMode > enuDealCardsMode.selectWeapon)
AnimateDealCards_drawMurderCards(g);
}
picBoard.Image = bmpTemp; picBoard.Refresh();
setDelayTimer(100);
udrAnimateDealCards.intAnimationCounter++;
}
void AnimateDealCards_SpreadCards(enuCardType eCardType, bool bolFaceUp)
{
classCard[] cAnimate = udrAnimateDealCards.udrTypeOrder.cRooms;
int intHGap = (int)(cCards[0].cBmp.getImage(0).Width * .45);
switch (eCardType)
{
case enuCardType.Suspect:
cAnimate = udrAnimateDealCards.udrTypeOrder.cSuspects;
intHGap = (int)(cCards[0].cBmp.getImage(0).Width * .65);
break;
case enuCardType.weapon:
cAnimate = udrAnimateDealCards.udrTypeOrder.cWeapons;
intHGap = (int)(cCards[0].cBmp.getImage(0).Width * .65);
break;
}
switch (udrAnimateDealCards.intAnimationCounter)
{
case 0: // init spread out top facing cards
Point ptBase = cAnimate[0].udrAnimationInfo.ptPos;
int intMaxSteps = 30;
for (int intCardCounter = 0; intCardCounter < cAnimate.Length; intCardCounter++)
{
classCard cThisCard = cAnimate[intCardCounter];
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd = new Point(ptBase.X + intCardCounter * intHGap, ptBase.Y);
cThisCard.udrAnimationInfo.intMaxSteps = intMaxSteps;
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.intStep = 0;
}
udrAnimateDealCards.intAnimationCounter++;
break;
case 1: // spread out cards
bool bolStartFlipCards = false;
Bitmap bmpTemp = new Bitmap(bmpDealAnimationBoard_Base);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (int intCardCounter = 0; intCardCounter < cAnimate.Length; intCardCounter++)
{
classCard cThisCard = cAnimate[intCardCounter];
cThisCard.udrAnimationInfo.ptPos = new Point(cThisCard.udrAnimationInfo.ptPos.X + (int)cThisCard.udrAnimationInfo.dblTravelInitialVelocity, cThisCard.udrAnimationInfo.ptPos.Y);
cThisCard.udrAnimationInfo.intStep++;
if (cThisCard.udrAnimationInfo.intStep >= cThisCard.udrAnimationInfo.intMaxSteps)
bolStartFlipCards = true;
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - cThisCard.cBmp.getImage(0).Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - cThisCard.cBmp.getImage(0).Height / 2);
if (bolFaceUp)
g.DrawImage(cThisCard.cBmp.getImage(0), ptTL);
else
g.DrawImage(cCardUnknown.cBmp.getImage(0), ptTL);
}
if (eDealMode > enuDealCardsMode.selectWeapon)
AnimateDealCards_drawMurderCards(g);
}
if (bolStartFlipCards)
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
picBoard.Image = bmpTemp; picBoard.Refresh();
break;
}
setDelayTimer(10);
}
void AnimateDealCards_GatherTypes()
{
switch (udrAnimateDealCards.intAnimationCounter)
{
case 0: // initialize card animations
int intMaxSteps = 10;
for (int intCardCounter = 0; intCardCounter < udrAnimateDealCards.cCardsCurrentAnimation.Length; intCardCounter++)
{
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[intCardCounter];
cThisCard.udrAnimationInfo.ptStart = cThisCard.udrAnimationInfo.ptPos;
cThisCard.udrAnimationInfo.ptEnd = ptAnimationTypeStackPos[(int)cThisCard.eType];
cThisCard.udrAnimationInfo.intMaxSteps = intMaxSteps;
cThisCard.udrAnimationInfo.intStep = 0;
if (cThisCard.udrAnimationInfo.dblAngleFacing > Math.PI)
cThisCard.udrAnimationInfo.dblAngleTurning = (dblTwoPi - cThisCard.udrAnimationInfo.dblAngleFacing) / cThisCard.udrAnimationInfo.intMaxSteps;
else
cThisCard.udrAnimationInfo.dblAngleTurning = -cThisCard.udrAnimationInfo.dblAngleFacing / cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(cThisCard.udrAnimationInfo.ptEnd, cThisCard.udrAnimationInfo.ptStart);
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.intMaxSteps;
}
udrAnimateDealCards.intAnimationCounter++;
udrAnimateDealCards.udrTypeOrder.cRooms = new classCard[0];
udrAnimateDealCards.udrTypeOrder.cSuspects = new classCard[0];
udrAnimateDealCards.udrTypeOrder.cWeapons = new classCard[0];
break;
case 1: // animate cards
bmpDealAnimationBoard = new Bitmap(bmpDealAnimationBoard_Base);
bool bolGatherTopCardsAndExit = false;
bool bolInsertIntoTypeOrder = (udrAnimateDealCards.udrTypeOrder.cSuspects.Length == 0);
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard))
{
for (int intCardCounter = 0; intCardCounter < udrAnimateDealCards.cCardsCurrentAnimation.Length; intCardCounter++)
{
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[intCardCounter];
if (bolInsertIntoTypeOrder)
{
switch (cThisCard.eType)
{
case enuCardType.room:
Array.Resize<classCard>(ref udrAnimateDealCards.udrTypeOrder.cRooms, udrAnimateDealCards.udrTypeOrder.cRooms.Length + 1);
udrAnimateDealCards.udrTypeOrder.cRooms[udrAnimateDealCards.udrTypeOrder.cRooms.Length - 1] = cThisCard;
break;
case enuCardType.weapon:
Array.Resize<classCard>(ref udrAnimateDealCards.udrTypeOrder.cWeapons, udrAnimateDealCards.udrTypeOrder.cWeapons.Length + 1);
udrAnimateDealCards.udrTypeOrder.cWeapons[udrAnimateDealCards.udrTypeOrder.cWeapons.Length - 1] = cThisCard;
break;
case enuCardType.Suspect:
Array.Resize<classCard>(ref udrAnimateDealCards.udrTypeOrder.cSuspects, udrAnimateDealCards.udrTypeOrder.cSuspects.Length + 1);
udrAnimateDealCards.udrTypeOrder.cSuspects[udrAnimateDealCards.udrTypeOrder.cSuspects.Length - 1] = cThisCard;
break;
}
}
cThisCard.udrAnimationInfo.intStep++;
if (cThisCard.udrAnimationInfo.intStep == cThisCard.udrAnimationInfo.intMaxSteps)
bolGatherTopCardsAndExit = true;
double dblFractionDistanceTravelled = ((double)cThisCard.udrAnimationInfo.intStep / (double)cThisCard.udrAnimationInfo.intMaxSteps) * cThisCard.udrAnimationInfo.dblTravelDistance;
cThisCard.udrAnimationInfo.ptPos = new Point(cThisCard.udrAnimationInfo.ptStart.X + (int)(dblFractionDistanceTravelled * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle)),
cThisCard.udrAnimationInfo.ptStart.Y + (int)(dblFractionDistanceTravelled * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle)));
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
int intImageIndex = (bolGatherTopCardsAndExit ? 0 : getImageIndex (cThisCard.udrAnimationInfo.dblAngleFacing));
Bitmap bmp = cThisCard.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
}
}
picBoard.Image = bmpDealAnimationBoard; picBoard.Refresh();
if (bolGatherTopCardsAndExit)
{
udrAnimateDealCards.cCardsCurrentAnimation = new classCard[0];
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
}
break;
}
setDelayTimer(100);
}
void AnimateDealCards_SortCardsIntoTypes()
{
if (udrAnimateDealCards.intAnimationCounter % 8 == 0 && udrAnimateDealCards.strCards.Length > 0)
{
// throw new card across the table
string strThisCard = udrAnimateDealCards.strCards.Substring(0, 2);
udrAnimateDealCards.strCards = udrAnimateDealCards.strCards.Substring(2);
enuCards eCard = (enuCards)Convert.ToInt16(strThisCard);
Array.Resize<classCard>(ref udrAnimateDealCards.cCardsCurrentAnimation, udrAnimateDealCards.cCardsCurrentAnimation.Length + 1);
udrAnimateDealCards.cCardsCurrentAnimation[udrAnimateDealCards.cCardsCurrentAnimation.Length - 1] = cCards[(int)eCard];
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[udrAnimateDealCards.cCardsCurrentAnimation.Length - 1];
Point ptStart = new Point(-50, -50);
Point ptEnd = new Point(1, 1);
switch (cThisCard.eType)
{
case enuCardType.room:
ptEnd = new Point((int)(bmpBoard.Width * .9), (int)(bmpBoard.Height * .25));
break;
case enuCardType.Suspect:
ptEnd = new Point((int)(bmpBoard.Width * .85), (int)(bmpBoard.Height * .75));
break;
case enuCardType.weapon:
ptEnd = new Point((int)(bmpBoard.Width * .25), (int)(bmpBoard.Height * .75));
break;
}
int intRangeError = (int)(bmpBoard.Height * .1);
ptEnd = new Point((int)(ptEnd.X + (int)(rnd.NextDouble() * 1000) % intRangeError * Math.Cos(rnd.NextDouble() * Math.PI * 2)),
(int)(ptEnd.Y + (int)(rnd.NextDouble() * 1000) % intRangeError * Math.Sin(rnd.NextDouble() * Math.PI * 2)));
cThisCard.udrAnimationInfo.ptStart = ptStart;
cThisCard.udrAnimationInfo.ptEnd = ptEnd;
cThisCard.udrAnimationInfo.dblTravelAcceleration = -15;
cThisCard.udrAnimationInfo.dblTravelAngle = classMath.arcTan(ptEnd, ptStart);
cThisCard.udrAnimationInfo.dblTravelDistance = classMath.distanceBetweenTwoPoints(ptEnd, ptStart);
cThisCard.udrAnimationInfo.intMaxSteps = (int)Math.Ceiling(Math.Sqrt(-2.0 * cThisCard.udrAnimationInfo.dblTravelDistance / cThisCard.udrAnimationInfo.dblTravelAcceleration));
cThisCard.udrAnimationInfo.dblTravelInitialVelocity = -cThisCard.udrAnimationInfo.dblTravelAcceleration * cThisCard.udrAnimationInfo.intMaxSteps;
cThisCard.udrAnimationInfo.dblAngleTurning = rnd.NextDouble() * Math.PI * (1.0 / 8.0);
cThisCard.udrAnimationInfo.intStep = 0;
cThisCard.udrAnimationInfo.dblAngleTurningAttenuation = 0.95;
}
udrAnimateDealCards.intAnimationCounter++;
bmpDealAnimationBoard = new Bitmap(bmpDealAnimationBoard_Base);
bool bolEndSortCards = true;
using (Graphics g = Graphics.FromImage(bmpDealAnimationBoard))
{
for (int intCardCounter = 0; intCardCounter < udrAnimateDealCards.cCardsCurrentAnimation.Length; intCardCounter++)
{
classCard cThisCard = udrAnimateDealCards.cCardsCurrentAnimation[intCardCounter];
if (cThisCard.udrAnimationInfo.intStep < cThisCard.udrAnimationInfo.intMaxSteps)
{
bolEndSortCards = false;
cThisCard.udrAnimationInfo.intStep++;
double dblDistanceTravelled = cThisCard.udrAnimationInfo.dblTravelInitialVelocity * cThisCard.udrAnimationInfo.intStep + .5 * cThisCard.udrAnimationInfo.dblTravelAcceleration * cThisCard.udrAnimationInfo.intStep * cThisCard.udrAnimationInfo.intStep;
cThisCard.udrAnimationInfo.ptPos = new Point(cThisCard.udrAnimationInfo.ptStart.X + (int)(dblDistanceTravelled * Math.Cos(cThisCard.udrAnimationInfo.dblTravelAngle)),
cThisCard.udrAnimationInfo.ptStart.Y + (int)(dblDistanceTravelled * Math.Sin(cThisCard.udrAnimationInfo.dblTravelAngle)));
cThisCard.udrAnimationInfo.dblAngleFacing += cThisCard.udrAnimationInfo.dblAngleTurning;
while (cThisCard.udrAnimationInfo.dblAngleFacing >= dblTwoPi)
cThisCard.udrAnimationInfo.dblAngleFacing -= dblTwoPi;
while (cThisCard.udrAnimationInfo.dblAngleFacing < 0)
cThisCard.udrAnimationInfo.dblAngleFacing += dblTwoPi;
cThisCard.udrAnimationInfo.dblAngleTurning *= cThisCard.udrAnimationInfo.dblAngleTurningAttenuation;
}
int intImageIndex = getImageIndex(cThisCard.udrAnimationInfo.dblAngleFacing);
Bitmap bmp = cThisCard.cBmp.getImage(intImageIndex);
Point ptTL = new Point(cThisCard.udrAnimationInfo.ptPos.X - bmp.Width / 2, cThisCard.udrAnimationInfo.ptPos.Y - bmp.Height / 2);
g.DrawImage(bmp, ptTL);
}
}
picBoard.Image = bmpDealAnimationBoard; picBoard.Refresh();
if (bolEndSortCards && udrAnimateDealCards.strCards.Length == 0)
{
eDealMode = (enuDealCardsMode)((int)eDealMode + 1);
udrAnimateDealCards.intAnimationCounter = 0;
}
setDelayTimer(10);
}
#endregion
#region "animate summonses"
void initSummonWeapon()
{
if (cWeapons[(int)udrSuggestion.eWeapon].eRoom == cSuspects[intSuspectTurn].eRoom)
{
cWeapons[(int)udrSuggestion.eWeapon].eRoom = cSuspects[intSuspectTurn].eRoom;
eMode = enuMode.respondToSuggestion;
drawBoard();
DrawSuggestingSuspect(); writeSuggestion();
ProveSuggestion();
return;
}
udrAniSummWeapon.ptStart = getWeaponGraphicPositionInRoom(udrSuggestion.eWeapon, cWeapons[(int)udrSuggestion.eWeapon].eRoom);
udrAniSummWeapon.ptEnd = getWeaponGraphicPositionInRoom(udrSuggestion.eWeapon, cSuspects[intSuspectTurn].eRoom);
udrAniSummWeapon.intStepCounter = 0;
udrAniSummWeapon.bolMoveToCenterOfScreen = true;
udrAniSummWeapon.intMaxSteps = 12;
udrAniSummWeapon.dblAngleBetweenPoints = classMath.arcTan((double)(udrAniSummWeapon.ptEnd.X - udrAniSummWeapon.ptStart.X), (double)(udrAniSummWeapon.ptEnd.Y - udrAniSummWeapon.ptStart.Y));
udrAniSummWeapon.dblDistanceBetweenPoints = Math.Sqrt(Math.Pow(udrAniSummWeapon.ptEnd.X - udrAniSummWeapon.ptStart.X, 2) + Math.Pow(udrAniSummWeapon.ptEnd.Y - udrAniSummWeapon.ptStart.Y, 2)) / 2;
udrAniSummWeapon.ptMidway = new Point((int)(udrAniSummWeapon.ptStart.X + udrAniSummWeapon.dblDistanceBetweenPoints * Math.Cos(udrAniSummWeapon.dblAngleBetweenPoints)),
(int)(udrAniSummWeapon.ptStart.Y + udrAniSummWeapon.dblDistanceBetweenPoints * Math.Sin(udrAniSummWeapon.dblAngleBetweenPoints)));
drawBoard();
bmpGameBoard = (Bitmap)picBoard.Image;
setDelayTimer(40);
}
void animateSummonWeapon()
{
udrAniSummWeapon.intStepCounter++;
if (udrAniSummWeapon.intStepCounter < udrAniSummWeapon.intMaxSteps)
{
Bitmap bmpTemp = new Bitmap(bmpGameBoard);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
double dblFractionDistance = ((double)udrAniSummWeapon.intStepCounter / (double)udrAniSummWeapon.intMaxSteps);
double dblPartDistance = udrAniSummWeapon.dblDistanceBetweenPoints * dblFractionDistance;
Point pt = new Point((int)(udrAniSummWeapon.ptStart.X + dblPartDistance * Math.Cos(udrAniSummWeapon.dblAngleBetweenPoints)),
(int)(udrAniSummWeapon.ptStart.Y + dblPartDistance * Math.Sin(udrAniSummWeapon.dblAngleBetweenPoints)));
int intTotalSizeDifference = (bmpWeapons_Board[0].Width - 35);
double dblFractionSize = ((double)udrAniSummWeapon.intStepCounter / (double)udrAniSummWeapon.intMaxSteps);
if (!udrAniSummWeapon.bolMoveToCenterOfScreen)
{
dblFractionSize = ((double)(udrAniSummWeapon.intMaxSteps - udrAniSummWeapon.intStepCounter) / (double)udrAniSummWeapon.intMaxSteps);
}
Size sz = new Size((int)(intTotalSizeDifference * dblFractionSize) + 35, (int)(intTotalSizeDifference * dblFractionSize) + 35);
Point ptTL = new Point(pt.X - sz.Width / 2, pt.Y - sz.Height / 2);
Rectangle recDest = new Rectangle(ptTL, sz);
Rectangle recSrc = new Rectangle(0, 0, bmpWeapons_Board[(int)udrSuggestion.eWeapon].Width, bmpWeapons_Board[(int)udrSuggestion.eWeapon].Height);
g.DrawImage(bmpWeapons_Board[(int)udrSuggestion.eWeapon], recDest, recSrc, GraphicsUnit.Pixel);
}
picBoard.Image = bmpTemp; picBoard.Refresh();
setDelayTimer(40);
}
else
{
if (udrAniSummWeapon.bolMoveToCenterOfScreen)
{
udrAniSummWeapon.ptStart = udrAniSummWeapon.ptMidway;
udrAniSummWeapon.intStepCounter = 0;
udrAniSummWeapon.bolMoveToCenterOfScreen = false;
udrAniSummWeapon.intMaxSteps = 12;
setDelayTimer(40);
}
else
{
cWeapons[(int)udrSuggestion.eWeapon].eRoom = cSuspects[intSuspectTurn].eRoom;
eMode = enuMode.respondToSuggestion;
drawBoard();
DrawSuggestingSuspect(); writeSuggestion();
ProveSuggestion();
}
}
}
void initSummonSuspect()
{
if (cSuspects[(int)udrSuggestion.eSuspect].eRoom == cSuspects[intSuspectTurn].eRoom)
{
eMode = enuMode.animateSummonWeapon;
return;
}
// set summoned suspect can suggest
cSuspects[(int)udrSuggestion.eSuspect].bolCanSuggest = true;
cSuspects[(int)udrSuggestion.eSuspect].bolHasNotYetMadeASuggestionThisTurn = false;
if (cSuspects[(int)udrSuggestion.eSuspect].eRoom == enuRooms.tiles)
udrAniSummSuspect.ptStart = getTileCenter(cSuspects[(int)udrSuggestion.eSuspect].ptTile);
else if (cSuspects[(int)udrSuggestion.eSuspect].eRoom == enuRooms.start)
udrAniSummSuspect.ptStart = new Point(cSuspects[(int)udrSuggestion.eSuspect].ptFirstTile.X * 28 + ptBoardTL.X, cSuspects[(int)udrSuggestion.eSuspect].ptFirstTile.Y * 28 + ptBoardTL.Y);
else
udrAniSummSuspect.ptStart = getPieceGraphicPositionInRoom(udrSuggestion.eSuspect, cSuspects[(int)udrSuggestion.eSuspect].eRoom);
udrAniSummSuspect.ptEnd = getPieceGraphicPositionInRoom(udrSuggestion.eSuspect, cSuspects[intSuspectTurn].eRoom);
udrAniSummSuspect.intStepCounter = 0;
udrAniSummSuspect.bolMoveToCenterOfScreen = true;
udrAniSummSuspect.intMaxSteps = 12;
udrAniSummSuspect.dblAngleBetweenPoints = classMath.arcTan((double)(udrAniSummSuspect.ptEnd.X - udrAniSummSuspect.ptStart.X), (double)(udrAniSummSuspect.ptEnd.Y - udrAniSummSuspect.ptStart.Y));
udrAniSummSuspect.dblDistanceBetweenPoints = Math.Sqrt(Math.Pow(udrAniSummSuspect.ptEnd.X - udrAniSummSuspect.ptStart.X, 2) + Math.Pow(udrAniSummSuspect.ptEnd.Y - udrAniSummSuspect.ptStart.Y, 2)) / 2;
udrAniSummSuspect.ptMidway = new Point((int)(udrAniSummSuspect.ptStart.X + udrAniSummSuspect.dblDistanceBetweenPoints * Math.Cos(udrAniSummSuspect.dblAngleBetweenPoints)),
(int)(udrAniSummSuspect.ptStart.Y + udrAniSummSuspect.dblDistanceBetweenPoints * Math.Sin(udrAniSummSuspect.dblAngleBetweenPoints)));
drawBoard();
setDelayTimer(40);
}
void animateSummonSuspect()
{
udrAniSummSuspect.intStepCounter++;
if (udrAniSummSuspect.intStepCounter < udrAniSummSuspect.intMaxSteps)
{
Bitmap bmpTemp = new Bitmap(bmpGameBoard);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
double dblFractionDistance = ((double)udrAniSummSuspect.intStepCounter / (double)udrAniSummSuspect.intMaxSteps);
double dblPartDistance = udrAniSummSuspect.dblDistanceBetweenPoints * dblFractionDistance;
Point pt = new Point((int)(udrAniSummSuspect.ptStart.X + dblPartDistance * Math.Cos(udrAniSummSuspect.dblAngleBetweenPoints)),
(int)(udrAniSummSuspect.ptStart.Y + dblPartDistance * Math.Sin(udrAniSummSuspect.dblAngleBetweenPoints)));
int intTotalSizeDifference = (bmpSuspects[0].Width - 35);
double dblFractionSize = ((double)udrAniSummSuspect.intStepCounter / (double)udrAniSummSuspect.intMaxSteps);
if (!udrAniSummSuspect.bolMoveToCenterOfScreen)
{
dblFractionSize = ((double)(udrAniSummSuspect.intMaxSteps - udrAniSummSuspect.intStepCounter) / (double)udrAniSummSuspect.intMaxSteps);
}
Size sz = new Size((int)(intTotalSizeDifference * dblFractionSize) + 35, (int)(intTotalSizeDifference * dblFractionSize) + 35);
Point ptTL = new Point(pt.X - sz.Width / 2, pt.Y - sz.Height / 2);
Rectangle recDest = new Rectangle(ptTL, sz);
Rectangle recSrc = new Rectangle(0, 0, bmpSuspects[(int)udrSuggestion.eSuspect].Width, bmpSuspects[(int)udrSuggestion.eSuspect].Height);
g.DrawImage(bmpSuspects[(int)udrSuggestion.eSuspect], recDest, recSrc, GraphicsUnit.Pixel);
}
picBoard.Image = bmpTemp; picBoard.Refresh();
setDelayTimer(40);
}
else
{
if (udrAniSummSuspect.bolMoveToCenterOfScreen)
{
udrAniSummSuspect.ptStart = udrAniSummSuspect.ptMidway;
udrAniSummSuspect.intStepCounter = 0;
udrAniSummSuspect.bolMoveToCenterOfScreen = false;
udrAniSummSuspect.intMaxSteps = 12;
setDelayTimer(40);
}
else
{
cSuspects[(int)udrSuggestion.eSuspect].eRoom = cSuspects[intSuspectTurn].eRoom;
eMode = enuMode.animateSummonWeapon;
}
}
}
#endregion
#region "debug"
//public void clearDebug()
//{
// System.IO.File.WriteAllText(strDebugFilename, "");
//}
//public void appendDebug(string strMessage)
//{
// strDebugFilename = strDebugFilename.ToUpper().Replace("DEBUG", "RELEASE");
// string strStatistics = "\r\n ---- statistics ---";
// string strOriginal = "";
// if (System.IO.File.Exists(strDebugFilename))
// strOriginal = System.IO.File.ReadAllText(strDebugFilename);
// int intCutChr = strOriginal.IndexOf(strStatistics);
// if (intCutChr >= 0)
// strOriginal = strOriginal.Substring(0, intCutChr - 1);
// strOriginal += "\r\n" + strMessage + "(" + DateTime.Now.ToString() + ")";
// string strCopy = strOriginal;
// string strCorrectlyIn = "Correctly in";
// intCutChr = strCopy.IndexOf(strCorrectlyIn);
// int[] intTurns = new int[100];
// int intNumGames = 0;
// while (intCutChr > 0)
// {
// intNumGames++;
// strCopy = strCopy.Substring(intCutChr + strCorrectlyIn.Length).Trim();
// intCutChr = strCopy.IndexOf(" ");
// if (intCutChr > 0)
// {
// int intThisNumTurn = Convert.ToInt16(strCopy.Substring(0, intCutChr));
// if (intThisNumTurn >= 0 && intThisNumTurn < intTurns.Length)
// intTurns[intThisNumTurn]++;
// }
// intCutChr = strCopy.IndexOf(strCorrectlyIn);
// }
// strOriginal += strStatistics;
// for (int intNumTurnsCounter = 0; intNumTurnsCounter < intTurns.Length; intNumTurnsCounter++)
// {
// if (intTurns[intNumTurnsCounter] > 0)
// {
// strOriginal += "\r\nsolved in " + intNumTurnsCounter.ToString() + " turns " + intTurns[intNumTurnsCounter].ToString() + " time" + (intTurns[intNumTurnsCounter] == 1 ? "" : "s") + " out of " + intNumGames.ToString() + " %" + ((double)intTurns[intNumTurnsCounter] / (double)intNumGames * 100.0).ToString("f2");
// }
// }
// System.IO.File.WriteAllText(strDebugFilename, strOriginal);
//}
#endregion
#region "helper functions"
Point getTileCenter(Point ptTile)
{
return new Point(ptBoardTL.X + ptTile.X * 28 + 14, ptBoardTL.Y + ptTile.Y * 28 + 14);
}
public bool floorTileIsFree(Point pt)
{
foreach (classSuspect cS in cSuspects)
if (cS.eRoom == enuRooms.tiles && cS.ptTile == pt)
return false;
return true;
}
bool validTile(Point pt)
{
return (pt.X >= 0 && pt.Y >= 0 && pt.X < sz.Width && pt.Y < sz.Height);
}
Point getPieceGraphicPositionInRoom(enuSuspects eSuspect) { return getPieceGraphicPositionInRoom(eSuspect, cSuspects[(int)eSuspect].eRoom); }
Point getPieceGraphicPositionInRoom(enuSuspects eSuspect, enuRooms eRoom)
{
double dblAlpha = (-Math.PI / 2 + Math.PI / 3.0) - (double)(int)eSuspect * (Math.PI / 3.0);
Point ptRoomCenter =getRoomCenter(eRoom);
double dblRadius = 40;
Point ptPieceCenter = new Point(ptRoomCenter.X + (int)(dblRadius * Math.Cos(dblAlpha)), ptRoomCenter.Y + (int)(dblRadius * Math.Sin(dblAlpha)));
return ptPieceCenter;
}
Point getWeaponGraphicPositionInRoom(enuWeapons eWeapon) { return getWeaponGraphicPositionInRoom(eWeapon, cWeapons[(int)eWeapon].eRoom); }
Point getWeaponGraphicPositionInRoom(enuWeapons eWeapon, enuRooms eRoom)
{
double dblAlpha = (double)(int)eWeapon * (Math.PI / 3.0);
Point ptRoomCenter = getRoomCenter(eRoom);
double dblRadius = 40;
Point ptWeaponCenter = new Point(ptRoomCenter.X + (int)(dblRadius * Math.Cos(dblAlpha)), ptRoomCenter.Y + (int)(dblRadius * Math.Sin(dblAlpha)));
return ptWeaponCenter;
}
public Bitmap getTextImage(string strText, Font fnt)
{ return getTextImage(strText, fnt, Color.Black); }
public Bitmap getTextImage(string strText, Font fnt, Color clr)
{
// use lblSize's 'autosize' mode to measure required output bitmap size
lblSizer.Text = strText;
lblSizer.Font = fnt;
Rectangle quoteRect = new Rectangle(0,
0,
lblSizer.Width
+ (fnt.Italic ? (int)(fnt.Height * .3) : 0)
+ (fnt.Bold ? (int)(fnt.Height * .2) : 0),
lblSizer.Height + 5);
// create a new bitmap that contains both the quote and the author text
Bitmap bmpTemp = new Bitmap(quoteRect.Width, quoteRect.Height);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
// set the text rendering characteristics
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
// draw the text
TextRenderer.DrawText(g,
strText,
fnt,
new Point(quoteRect.X + 5,
quoteRect.Y),
clr,
Color.White,
TextFormatFlags.Default | TextFormatFlags.NoPrefix);
}
bmpTemp.MakeTransparent(Color.White);
int intLeftCut = 7;
int intWidth = bmpTemp.Width - intLeftCut;
if (intWidth <= 0)
intWidth = 1;
Bitmap bmpRetVal = new Bitmap(intWidth, bmpTemp.Height);
using (Graphics g = Graphics.FromImage(bmpRetVal))
{
Rectangle rectDest = new Rectangle(0, 0, quoteRect.Width, bmpRetVal.Height);
Rectangle rectSrc = new Rectangle(intLeftCut, 0, quoteRect.Width, bmpRetVal.Height);
g.DrawImage(bmpTemp, rectDest, rectSrc, GraphicsUnit.Pixel);
}
return bmpRetVal;
}
Point getRoomCenter(enuRooms eRoom)
{
if (ptRoomCenters == null || true)
{
ptRoomCenters = new Point[(int)enuRooms._numRooms + 1];
for (enuRooms eRoomCounter = (enuRooms)0; eRoomCounter <= enuRooms._numRooms; eRoomCounter++)
{
switch (eRoomCounter)
{
case enuRooms.Study:
ptRoomCenters[(int)eRoomCounter] = new Point(110, 60);
break;
case enuRooms.Hall:
ptRoomCenters[(int)eRoomCounter] = new Point(358, 100);
break;
case enuRooms.Lounge:
ptRoomCenters[(int)eRoomCounter] = new Point(596, 82);
break;
case enuRooms.DiningRoom:
ptRoomCenters[(int)eRoomCounter] = new Point(591, 332);
break;
case enuRooms.Kitchen:
ptRoomCenters[(int)eRoomCounter] = new Point(610, 580);
break;
case enuRooms.BallRoom:
ptRoomCenters[(int)eRoomCounter] = new Point(367, 564);
break;
case enuRooms.Conservatory:
ptRoomCenters[(int)eRoomCounter] = new Point(103, 611);
break;
case enuRooms.BilliardRoom:
ptRoomCenters[(int)eRoomCounter] = new Point(106, 409);
break;
case enuRooms.Library:
ptRoomCenters[(int)eRoomCounter] = new Point(122, 242);
break;
case enuRooms._numRooms:
ptRoomCenters[(int)eRoomCounter] = new Point(349, 328);
break;
}
}
}
return ptRoomCenters[(int)eRoom];
}
public enuRooms getERoomFromCard(enuCards eRoomCard)
{
try
{
if (classCard.eCardIsARoom(eRoomCard))
return (enuRooms)((int)eRoomCard - (int)enuSuspects._numSuspects - (int)enuWeapons._numWeapons);
}
catch (Exception)
{
}
return enuRooms._numRooms;
}
public enuCards getCardFromERoom(enuRooms eRoom)
{
string strERoom = eRoom.ToString();
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
if (eCardCounter.ToString() == strERoom)
return eCardCounter;
return enuCards._numCards;
}
public enuSuspects getESuspectFromCard(enuCards eSuspectCard)
{
try
{
if (classCard.eCardIsASuspect(eSuspectCard))
return (enuSuspects)((int)eSuspectCard);
}
catch (Exception)
{
}
return enuSuspects._numSuspects;
}
public enuCards getCardFromESuspect(enuSuspects eSuspect)
{
string streSuspect = eSuspect.ToString();
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
if (eCardCounter.ToString() == streSuspect)
return eCardCounter;
return enuCards._numCards;
}
public enuWeapons getEWeaponFromCard(enuCards eWeaponCard)
{
try
{
if (classCard.eCardIsAWeapon(eWeaponCard))
return (enuWeapons)((int)eWeaponCard - (int)enuSuspects._numSuspects);
}
catch (Exception) { }
return enuWeapons._numWeapons;
}
public enuCards getCardFromEWeapon(enuWeapons eWeapon)
{
string streWeapon = eWeapon.ToString();
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
if (eCardCounter.ToString() == streWeapon)
return eCardCounter;
return enuCards._numCards;
}
public enuDir getOppDir(enuDir dirIn) { return (enuDir)(((int)dirIn + 2) % 4); }
void appendCardList(ref enuCards[] eCardList, enuCards eCard)
{
if (eCardList == null)
eCardList = new enuCards[0];
Array.Resize<enuCards>(ref eCardList, eCardList.Length + 1);
eCardList[eCardList.Length - 1] = eCard;
}
bool eCardIsInListeCards(ref classCard[] cCardList, enuCards eCard)
{
for (int intCardCounter = 0; intCardCounter < cCardList.Length; intCardCounter++)
if (cCardList[intCardCounter].eCardName == eCard)
return true;
return false;
}
public Point movePoint(Point pt, enuDir dir)
{
switch (dir)
{
case enuDir.north:
if (pt.Y < 1)
return new Point(-1, -1);
else
return new Point(pt.X, pt.Y - 1);
case enuDir.east:
if (pt.X > sz.Width - 1)
return new Point(-1, -1);
else
return new Point(pt.X + 1, pt.Y);
case enuDir.south:
if (pt.Y > sz.Height - 1)
return new Point(-1, -1);
else
return new Point(pt.X, pt.Y + 1);
case enuDir.west:
if (pt.X < 1)
return new Point(-1, -1);
else
return new Point(pt.X - 1, pt.Y);
}
return new Point(-1, -1);
}
bool RoomDoor(ref classRoom cRoom, Point pt)
{
for (int intDoorCounter = 0; intDoorCounter < cRoom.ptDoors.Length; intDoorCounter++)
{
if (cRoom.ptDoors[intDoorCounter] == pt)
return true;
}
return false;
}
void setPtMouseTile(int intX, int intY)
{
ptMouseTile = new Point((intX - ptBoardTL.X) / 28, (intY - ptBoardTL.Y) / 28);
}
enuSuspects getMouseOverAISuspect(Point pt)
{
if (pt.Y > 39 && pt.Y < 64)
{ // Col.Mustard
return enuSuspects.ColMustard;
}
else if (pt.Y > 65 && pt.Y < 90)
{ // Prof Plum
return enuSuspects.ProfPlum;
}
else if (pt.Y > 91 && pt.Y < 118)
{ // Rev.Green
return enuSuspects.RevGreen;
}
else if (pt.Y > 119 && pt.Y < 144)
{ // Mrs.Peacock
return enuSuspects.MrsPeacock;
}
else if (pt.Y > 145 && pt.Y < 170)
{ // Miss Scarlet
return enuSuspects.MissScarlet;
}
else if (pt.Y > 171 && pt.Y < 196)
{ // Mrs.White
return enuSuspects.MrsWhite;
}
else
return enuSuspects._numSuspects;
}
#endregion
public enuMode eMode
{
get { return _eMode; }
set
{
_eMode = value;
switch (_eMode)
{
case enuMode.chooseCharacter:
pnlControls.Enabled = false;
cLibPicTrayWeapons.Visible = false;
break;
case enuMode.Accuse:
pnlControls.Enabled = false;
if (cSuspects[intSuspectTurn].bolPlayerControlled)
ShowAccuseOptions();
break;
case enuMode.Suggest:
pnlControls.Enabled = false;
Suggest();
break;
case enuMode.animateIntroduction:
initAnimateIntroduction();
break;
case enuMode.animateSummonSuspect:
initSummonSuspect();
break;
case enuMode.animateSummonWeapon:
initSummonWeapon();
break;
case enuMode.respondToSuggestion:
break;
case enuMode.animateSecretPassage:
initAnimateSecretPassage();
break;
case enuMode.warnPlayerNextTurn:
btnChooseSuspect.Visible =
cLibPicTraySuspects.Visible =
cLibPicTrayWeapons.Visible = false;
btnEndTurn.Enabled = false;
btnSuggest.Enabled = cSuspects[intSuspectTurn].bolCanSuggest;
grbControls.BackColor = clrSuspects[intSuspectTurn]; grbControls.Refresh();
pnlControls.Enabled = false;
btnRollDie.PulseColor
= grbControls.ForeColor = Color.FromArgb((grbControls.BackColor.A + 126) % 255,
(grbControls.BackColor.R + 126) % 255,
(grbControls.BackColor.G + 126) % 255,
(grbControls.BackColor.B + 126) % 255);
grbControls.Text = cSuspects[intSuspectTurn].eName.ToString();
picBoard.SendToBack(); picBoard.Refresh();
drawBoard();
warnPlayerWhoseTurnItIs();
break;
case enuMode.beginTurn:
btnRollDie.Enabled = true;
grbControls.Visible = true;
eraseWarnPlayerWhoseTurnItIs();
picBoard.SendToBack();
picNotebook.Refresh();
pnlControls.Enabled = true;
cSuspects[intSuspectTurn].allowSecretPassage();
drawBoard();
if (!cSuspects[intSuspectTurn].bolPlayerControlled)
{
cSuspects[intSuspectTurn].playTurn();
}
else
eMode = enuMode.playerTurnIdle;
break;
case enuMode.endTurn:
cSuspects[intSuspectTurn].bolCanSuggest = false;
cSuspects[intSuspectTurn].resetAllowableMoves();
if (!cSuspects[intSuspectTurn].bolPlayerControlled)
{
if (eMode != enuMode.respondToSuggestion && eMode != enuMode.Suggest)
{
drawBoard();
nextPlayer();
}
}
else
nextPlayer();
break;
case enuMode.rollDie_animate:
setDelayTimer(5);
break;
case enuMode.rollDie_end:
rollDie_End();
break;
case enuMode.dealCards:
btnChooseSuspect.Visible =
cLibPicTraySuspects.Visible =
cLibPicTrayWeapons.Visible = false;
udrAnimateDealCards.bolQuitAnimation = false;
eDealMode = (enuDealCardsMode)0;
eDealMode = (enuDealCardsMode)1;
break;
}
}
}
void initResponseBubble()
{
bmpResponseBubble = new Bitmap(bmpSuggestionBubble, new Size(400, 120));
bmpResponseBubble.RotateFlip(RotateFlipType.RotateNoneFlipX);
bmpResponseBubble.MakeTransparent();
}
void PlayerChoosesCardToShowBannerClick()
{
autoProceedEnabled = false;
picBoard.Image = bmpSuggestionBoard; picBoard.Refresh();
eMode = enuMode.respondToSuggestion;
ProveSuggestion_ReceiveResponse(getPlayerSuspect().eName, enuCards.NoCardShown);
}
public void btnMakeSuggestion_OK_click()
{
autoProceedEnabled = false;
cLibPicTraySuspects.Visible = false;
cLibPicTrayWeapons.Visible = false;
eMode = enuMode.respondToSuggestion;
cButtons[(int)enuButtons.MakeSuggestion_Cancel].erase();
cButtons[(int)enuButtons.MakeSuggestion_Ok].erase();
eMode = enuMode.animateSummonSuspect;
}
void btnMakeSuggestion_Cancel_click()
{
cSuspects[intSuspectTurn].bolCanSuggest = true;
cLibPicTraySuspects.Visible = false;
cLibPicTrayWeapons.Visible = false;
btnSuggest.Enabled = pnlControls.Enabled = true;
eMode = enuMode.playerTurnIdle;
drawBoard();
}
void btnRespondSuggestion_OK_click()
{
autoProceedEnabled = false;
if (udrSuggestionAnimation.intProveSuggestionCycleCounter < (int)enuSuspects._numSuspects)
ProveSuggestion_CycleThroughSuspects();
else
{
drawBoard();
pnlControls.Enabled = true;
if (cSuspects[intSuspectTurn].bolPlayerControlled)
eMode = enuMode.playerTurnIdle;
else
{
if (cSuspects[intSuspectTurn].bolMustMove)
{
eMode = enuMode.AISuggestionComplete;
cSuspects[intSuspectTurn].playTurn();
}
else
eMode = enuMode.endTurn;
}
}
}
bool buttonPressed()
{
if (eMode == enuMode.playerChoosesCardToShow)
{
if (ptMousePos.X > recBannerButton.Left && ptMousePos.X < recBannerButton.Left + recBannerButton.Width)
if (ptMousePos.Y > recBannerButton.Top && ptMousePos.Y < recBannerButton.Top + recBannerButton.Height)
{
if (btnPlayerResponse[0].Visible)
return false; // there are cards to show ignore this click
PlayerChoosesCardToShowBannerClick();
return true;
}
}
if (cButtons[(int)enuButtons.MouseOver] == null)
return false;
switch (eMode)
{
case enuMode.Suggest:
if (cButtons[(int)enuButtons.MouseOver] == cButtons[(int)enuButtons.MakeSuggestion_Ok])
{
btnMakeSuggestion_OK_click();
return true;
}
else if (cButtons[(int)enuButtons.MouseOver] == cButtons[(int)enuButtons.MakeSuggestion_Cancel]
&& cSuspects[intSuspectTurn].bolPlayerControlled)
{
btnMakeSuggestion_Cancel_click();
return true;
}
break;
case enuMode.respondToSuggestion:
if (cButtons[(int)enuButtons.MouseOver] == cButtons[(int)enuButtons.RespondToSuggestion_Ok])
{
btnRespondSuggestion_OK_click();
}
break;
}
return false;
}
void pic_MouseClick(object sender, MouseEventArgs e)
{ // this is the event-handler called when player clicks picBoard or picNote
if ((eMode == enuMode.showAllowableMoves && !cSuspects[intSuspectTurn].bolPlayerControlled)
|| (eMode == enuMode.showAllowableMoves && !validTile(ptMouseTile))
|| bolDisableMouseClickBoard
|| !bolInit)
return;
picMouseClick(sender, e);
}
public void picMouseClick(object sender, MouseEventArgs e)
{ // this is the function which the AI calls to activate a move
if (!bolInit)
return;
if (eMode == enuMode.dealCards || eMode == enuMode.idle)
{
udrAnimateDealCards.bolQuitAnimation = true;
return;
}
if (buttonPressed())
return;
setPtMouseTile(e.X, e.Y);
if (!validTile(ptMouseTile))
return;
bolDisableMouseClickBoard = true;
classSuspect cSus = cSuspects[intSuspectTurn];
if (cSus.cSEAllowableMoves[ptMouseTile.X, ptMouseTile.Y] != null)
{
if (classSuspect.cFloor[ptMouseTile.X, ptMouseTile.Y].eType == enuFloor.door
&& classSuspect.cFloor[ptMouseTile.X, ptMouseTile.Y].dirDoor == enuDir.secretPassage)
{
eMode = enuMode.animateSecretPassage;
bolDisableMouseClickBoard = false;
return;
}
else
{
btnRollDie.Enabled = false;
btnEndTurn.Enabled = true;
if (cSus.eRoom == enuRooms.start)
{
cSus.eRoom = enuRooms.tiles;
cSus.ptTile = cSus.ptFirstTile;
}
// animate suspect walking
// calculate path from current tile to clicked-tile by working backwards
udrMoveAnimationInfo.strPath = "";
classSearchElement cSE = cSus.cSEAllowableMoves[ptMouseTile.X, ptMouseTile.Y];
classRoom cRoom = null;
if (cSus.eRoom < enuRooms._numRooms)
cRoom = cRooms[(int)cSus.eRoom];
Point ptNext = cSus.ptTile;
enuDir dirStep;
while (cSE != null
&& ((cSus.eRoom == enuRooms.tiles && cSE != cSus.cSEAllowableMoves[cSus.ptTile.X, cSus.ptTile.Y]) // suspect is on tile and tile has been reached
|| (cSus.eRoom < enuRooms._numRooms && !RoomDoor(ref cRoom, cSE.pt)))) // suspect is in a room and one of the room's doors has been reached
{
dirStep = getOppDir(cSE.SrcDir);
udrMoveAnimationInfo.strPath = ((int)dirStep).ToString() + udrMoveAnimationInfo.strPath;
ptNext = movePoint(cSE.pt, cSE.SrcDir);
cSE = cSus.cSEAllowableMoves[ptNext.X, ptNext.Y];
}
if (cSus.eRoom < enuRooms._numRooms) // suspect is in a room -> ptNext points to door (not included in allowable steps)
{
cSus.ptTile = ptNext;
cSus.eRoom = enuRooms.tiles;
}
eMode = enuMode.animateMove;
cSus.resetAllowableMoves(); drawBoard();
udrMoveAnimationInfo.bmpAnimationBoard = new Bitmap(picBoard.Image);
udrMoveAnimationInfo.ptImage = new Point(ptBoardTL.X + cSus.ptTile.X * 28 + 2, ptBoardTL.Y + cSus.ptTile.Y * 28 + 2);
udrMoveAnimationInfo.recPiece = new Rectangle(udrMoveAnimationInfo.ptImage.X, udrMoveAnimationInfo.ptImage.Y, 28, 28);
udrMoveAnimationInfo.ptMouseTile = ptMouseTile;
startMoveAnimation();
return;
}
drawBoard();
}
bolDisableMouseClickBoard = false;
}
void Pic_MouseMove(object sender, MouseEventArgs e)
{
if (!bolInit)
return;
if (bolDisableMouseClickBoard)
return;
ptMousePos = new Point(e.X, e.Y);
setPtMouseTile(e.X, e.Y);
cButtons[(int)enuButtons.MouseOver] = getMouseOverButton(new Point(e.X, e.Y));
}
void picBoard_MouseEnter(object sender, EventArgs e)
{
if (!bolInit)
return;
hideOptions();
}
#region "animate Move"
void startMoveAnimation()
{
udrMoveAnimationInfo.intAnimationStep = 4;
udrMoveAnimationInfo.cSus = cSuspects[intSuspectTurn];
eMode = enuMode.animateMove;
moveStep();
}
void moveStep()
{
enuDir dirStep;
startMoveStep:
if (udrMoveAnimationInfo.intAnimationStep < 4)
{
using (Graphics g = Graphics.FromImage(udrMoveAnimationInfo.bmpAnimationBoard))
{ // erase old image of suspect off game board
g.DrawImage(bmpBoard, udrMoveAnimationInfo.recPiece, udrMoveAnimationInfo.recPiece, GraphicsUnit.Pixel);
// move ptImage
udrMoveAnimationInfo.ptImage = new Point(udrMoveAnimationInfo.ptImage.X + udrMoveAnimationInfo.ptAnimationMove.X, udrMoveAnimationInfo.ptImage.Y + udrMoveAnimationInfo.ptAnimationMove.Y);
// create new rectangle for altered position
udrMoveAnimationInfo.recPiece = new Rectangle(udrMoveAnimationInfo.ptImage.X, udrMoveAnimationInfo.ptImage.Y, 28, 28);
// draw new image of suspect onto game board
g.DrawImage(bmpPieces[intSuspectTurn], udrMoveAnimationInfo.recPiece, new Rectangle(0, 0, 28, 28), GraphicsUnit.Pixel);
picBoard.Image = udrMoveAnimationInfo.bmpAnimationBoard; picBoard.Refresh();
udrMoveAnimationInfo.intAnimationStep++;
setDelayTimer(40);
return;
}
}
else if (udrMoveAnimationInfo.strPath.Length > 0)
{
string strStep = udrMoveAnimationInfo.strPath.Substring(0, 1);
udrMoveAnimationInfo.strPath = udrMoveAnimationInfo.strPath.Substring(1);
dirStep = (enuDir)(Convert.ToInt16(strStep));
switch (dirStep)
{
case enuDir.north:
udrMoveAnimationInfo.ptAnimationMove = new Point(0, -7);
break;
case enuDir.east:
udrMoveAnimationInfo.ptAnimationMove = new Point(7, 0);
break;
case enuDir.south:
udrMoveAnimationInfo.ptAnimationMove = new Point(0, 7);
break;
default:
case enuDir.west:
udrMoveAnimationInfo.ptAnimationMove = new Point(-7, 0);
break;
}
udrMoveAnimationInfo.intAnimationStep = 0;
goto startMoveStep;
}
udrMoveAnimationInfo.cSus.ptTile = udrMoveAnimationInfo.ptMouseTile;
if (classSuspect.cFloor[udrMoveAnimationInfo.cSus.ptTile.X, udrMoveAnimationInfo.cSus.ptTile.Y].eType == enuFloor.door)
{
udrMoveAnimationInfo.cSus.eRoom = classSuspect.cFloor[udrMoveAnimationInfo.cSus.ptTile.X, udrMoveAnimationInfo.cSus.ptTile.Y].eRoom;
udrMoveAnimationInfo.cSus.bolCanSuggest = cSuspects[intSuspectTurn].bolHasNotYetMadeASuggestionThisTurn;
btnSuggest.Enabled = cSuspects[intSuspectTurn].bolHasNotYetMadeASuggestionThisTurn;
}
else
{
udrMoveAnimationInfo.cSus.eRoom = enuRooms.tiles;
btnSuggest.Enabled = cSuspects[intSuspectTurn].bolCanSuggest = false;
}
drawBoard();
bolDisableMouseClickBoard = false;
if (!udrMoveAnimationInfo.cSus.bolPlayerControlled)
udrMoveAnimationInfo.cSus.playTurnAfterMove();
else
{
pnlControls.Enabled = true;
btnAccuse.Enabled = btnEndTurn.Enabled = true;
eMode = enuMode.playerTurnIdle;
}
}
#endregion
void initAnimateSecretPassage()
{
grbControls.Enabled = btnRollDie.Enabled = false;
udrAniSecretPassage.eRoom_End = cRooms[(int) cSuspects[intSuspectTurn].eRoom].oppositeCornerRoom();
udrAniSecretPassage.eRoom_Start = cSuspects[intSuspectTurn].eRoom;
udrAniSecretPassage.ptStart = getPieceGraphicPositionInRoom((enuSuspects)intSuspectTurn, cSuspects[intSuspectTurn].eRoom);
udrAniSecretPassage.ptEnd = getPieceGraphicPositionInRoom((enuSuspects)intSuspectTurn, udrAniSecretPassage.eRoom_End);
udrAniSecretPassage.intStepCounter = 0;
udrAniSecretPassage.bolMoveToCenterOfScreen = true;
udrAniSecretPassage.intMaxSteps = 12;
udrAniSecretPassage.dblAngleBetweenPoints = classMath.arcTan((double)(udrAniSecretPassage.ptEnd.X - udrAniSecretPassage.ptStart.X), (double)(udrAniSecretPassage.ptEnd.Y - udrAniSecretPassage.ptStart.Y));
udrAniSecretPassage.dblDistanceBetweenPoints = Math.Sqrt(Math.Pow(udrAniSecretPassage.ptEnd.X - udrAniSecretPassage.ptStart.X, 2) + Math.Pow(udrAniSecretPassage.ptEnd.Y - udrAniSecretPassage.ptStart.Y, 2)) / 2;
udrAniSecretPassage.ptMidway = new Point((int)(udrAniSecretPassage.ptStart.X + udrAniSecretPassage.dblDistanceBetweenPoints * Math.Cos(udrAniSecretPassage.dblAngleBetweenPoints)),
(int)(udrAniSecretPassage.ptStart.Y + udrAniSecretPassage.dblDistanceBetweenPoints * Math.Sin(udrAniSecretPassage.dblAngleBetweenPoints)));
cSuspects[intSuspectTurn].resetAllowableMoves(); drawBoard();
setDelayTimer(40);
}
void AnimateSecretPassage()
{
udrAniSecretPassage.intStepCounter++;
if (udrAniSecretPassage.intStepCounter < udrAniSecretPassage.intMaxSteps)
{
Bitmap bmpTemp = new Bitmap(bmpGameBoard);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
double dblFractionDistance = ((double)udrAniSecretPassage.intStepCounter / (double)udrAniSecretPassage.intMaxSteps);
double dblPartDistance = udrAniSecretPassage.dblDistanceBetweenPoints * dblFractionDistance;
Point pt = new Point((int)(udrAniSecretPassage.ptStart.X + dblPartDistance * Math.Cos(udrAniSecretPassage.dblAngleBetweenPoints)),
(int)(udrAniSecretPassage.ptStart.Y + dblPartDistance * Math.Sin(udrAniSecretPassage.dblAngleBetweenPoints)));
int intTotalSizeDifference = (bmpSuspects[0].Width - 35);
double dblFractionSize = ((double)udrAniSecretPassage.intStepCounter / (double)udrAniSecretPassage.intMaxSteps);
if (!udrAniSecretPassage.bolMoveToCenterOfScreen)
{
dblFractionSize = ((double)(udrAniSecretPassage.intMaxSteps - udrAniSecretPassage.intStepCounter) / (double)udrAniSecretPassage.intMaxSteps);
}
Size sz = new Size((int)(intTotalSizeDifference * dblFractionSize) + 35, (int)(intTotalSizeDifference * dblFractionSize) + 35);
Point ptTL = new Point(pt.X - sz.Width / 2, pt.Y - sz.Height / 2);
Rectangle recDest = new Rectangle(ptTL, sz);
Rectangle recSrc = new Rectangle(0, 0, bmpSuspects[(int)intSuspectTurn].Width, bmpSuspects[(int)intSuspectTurn].Height);
g.DrawImage(bmpSuspects[(int)intSuspectTurn], recDest, recSrc, GraphicsUnit.Pixel);
}
picBoard.Image = bmpTemp; picBoard.Refresh();
setDelayTimer(40);
}
else
{
if (udrAniSecretPassage.bolMoveToCenterOfScreen)
{
udrAniSecretPassage.ptStart = udrAniSecretPassage.ptMidway;
udrAniSecretPassage.intStepCounter = 0;
udrAniSecretPassage.bolMoveToCenterOfScreen = false;
udrAniSecretPassage.intMaxSteps = 12;
setDelayTimer(40);
}
else
{
cSuspects[intSuspectTurn].eRoom = udrAniSecretPassage.eRoom_End;
btnRollDie.Enabled = false;
grbControls.Enabled
= btnEndTurn.Enabled
= btnSuggest.Enabled
= cSuspects[intSuspectTurn].bolCanSuggest = true;
bolDisableMouseClickBoard = false;
eMode = enuMode.playerTurnIdle;
if (!cSuspects[intSuspectTurn].bolPlayerControlled)
{
cSuspects[intSuspectTurn].bolMustMove = false;
cSuspects[intSuspectTurn].makeSuggestion();
}
drawBoard();
}
}
}
classButton getMouseOverButton(Point ptMouse)
{
for (enuButtons eButtonCounter = 0; eButtonCounter < enuButtons._numButtons; eButtonCounter++)
{
if (cButtons[(int)eButtonCounter] != null)
{
classButton cThisButton = cButtons[(int)eButtonCounter];
if (ptMouse.X > cThisButton.pt.X && ptMouse.X < cThisButton.pt.X + cThisButton.sz.Width)
if (ptMouse.Y > cThisButton.pt.Y && ptMouse.Y < cThisButton.pt.Y + cThisButton.sz.Height)
{
if (cThisButton.eMode == enuMode.any
|| cThisButton.eMode == eMode)
{
if (cButtons[(int)enuButtons.MouseOver] != cThisButton)
{
if (cButtons[(int)enuButtons.MouseOver] != null)
cButtons[(int)enuButtons.MouseOver].draw();
cThisButton.highlight();
}
return cThisButton;
}
}
}
}
if (cButtons[(int)enuButtons.MouseOver] != null)
cButtons[(int)enuButtons.MouseOver].draw();
return null;
}
void PlaceControls()
{
Controls.Add(picBoard);
picBoard.SizeMode = PictureBoxSizeMode.Normal;
Bitmap bmpTemp = new Bitmap(bmpBoard.Width + 5 + bmpNotebook.Width, bmpBoard.Height);
Bitmap bmpLogo = new Bitmap(Clue_CS2010.Properties.Resources.clue_logo);
bmpLogo.MakeTransparent();
Point ptTLLogo = new Point((bmpTemp.Width - bmpLogo.Width) / 2, (bmpTemp.Height - bmpLogo.Height) / 2);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.DrawImage(bmpBoard, new Point(0, 0));
g.DrawImage(bmpNotebook, new Point(bmpBoard.Width + 5, 0));
g.DrawImage(bmpLogo, ptTLLogo );
}
picBoard.Image = bmpTemp;
picBoard.Location = new Point(0, 25);
picBoard.Controls.Add(btnAccuse_Ok);
pnlNotebook.Left = picBoard.Left + Clue_CS2010.Properties.Resources.ClueBoardMarble.Width + 5;
pnlNotebook.Top = picBoard.Top;
grbControls.Location = new Point(pnlNotebook.Left + pnlNotebook.Width + 5, picNotebook.Top);
grbControls.Width = Screen.PrimaryScreen.WorkingArea.Width - grbControls.Left - 10;
grbControls.Height = picNotebook.Height;
grbControls.Top = picBoard.Top;
picBoard.Width = pnlNotebook.Left + 240;
picBoard.Height = Screen.PrimaryScreen.WorkingArea.Height;
picNotebook.BringToFront();
bringControlsUpFront();
picDieBox.Left = 5;
picDieBox.Width = grbControls.Width - 10;
pnlControls.Top = 25;
pnlControls.Left = 5;
pnlControls.Width = grbControls.Width-10;
btnEndTurn.Left = btnRollDie.Left = btnAccuse.Left = btnSuggest.Left = 5;
btnEndTurn.Width = btnRollDie.Width = btnSuggest.Width = pnlControls.Width - 10;
btnSuggest.Top = 0;
btnRollDie.Top = btnSuggest.Top + btnSuggest.Height + 5;
btnEndTurn.Top = btnRollDie.Top + btnRollDie.Height + 5;
pnlControls.Height = btnEndTurn.Top + btnEndTurn.Height + 5;
btnAccuse.Top = grbControls.Height - btnAccuse.Height - 5;
btnAccuse.Width = grbControls.Width - 10;
btnAccuse.Left = 5;
picDieBox.Top = pnlControls.Top + pnlControls.Height + 5;
picDieBox.Height = btnAccuse.Top - picDieBox.Top - 5;
picDieBox.Visible = true;
btnChooseSuspect.BackColor = Color.Transparent;
btnChooseSuspect.Click += new EventHandler(btnChooseSuspect_Click);
btnChooseSuspect.Visible = false;
lblSizer.AutoSize = true;
Controls.Add(lblSizer);
lblSizer.Top = Screen.PrimaryScreen.WorkingArea.Height + 10;
lblSizer.Visible = true;
picBoard.MouseLeave += new EventHandler(picBoard_MouseLeave);
picBoard.MouseMove += new MouseEventHandler(Pic_MouseMove);
picBoard.MouseClick += new MouseEventHandler(pic_MouseClick);
picBoard.MouseEnter += new EventHandler(picBoard_MouseEnter);
picNotebook.MouseLeave += new EventHandler(picNotebook_MouseLeave);
picNotebook.MouseMove += new MouseEventHandler(picNotebook_MouseMove);
picNotebook.MouseClick += new MouseEventHandler(picNotebook_MouseClick);
picNotebook.MouseWheel += new MouseEventHandler(picNotebook_MouseWheel);
grbSetAI.Left = (Screen.PrimaryScreen.WorkingArea.Width - grbSetAI.Width) / 2;
grbSetAI.Top = (Screen.PrimaryScreen.WorkingArea.Height - grbSetAI.Height) / 2;
grbSetAI.MouseClick += new MouseEventHandler(grbSetAI_MouseClick);
grbSetAI.MouseEnter += new EventHandler(grbSetAI_MouseEnter);
grbSpeed.Left = (Screen.PrimaryScreen.WorkingArea.Width - grbSpeed.Width) / 2;
grbSpeed.Top = (Screen.PrimaryScreen.WorkingArea.Height - grbSpeed.Height) / 2;
grbSpeed.MouseEnter += new EventHandler(grbSpeed_MouseEnter);
chkSpeed_AutoProceed.CheckedChanged += new EventHandler(chkSpeed_AutoProceed_CheckedChanged);
chkSpeed_AutoProceed.Checked = true;
hsbSpeed.ValueChanged += new EventHandler(hsbSpeed_ValueChanged);
Controls.Add(proBar);
proBar.Top = ptTLLogo.Y + bmpLogo.Height + 35;
proBar.Width = (int)(Screen.PrimaryScreen.WorkingArea.Width * .3);
proBar.Left = (Screen.PrimaryScreen.WorkingArea.Width - proBar.Width) / 2;
proBar.BringToFront();
proBar.Visible = false;
for (int intPlayerResponseButtonCounter = 0; intPlayerResponseButtonCounter < btnPlayerResponse.Length; intPlayerResponseButtonCounter++)
{
btnPlayerResponse[intPlayerResponseButtonCounter] = new Button();
picBoard.Controls.Add(btnPlayerResponse[intPlayerResponseButtonCounter]);
btnPlayerResponse[intPlayerResponseButtonCounter].Visible = false;
btnPlayerResponse[intPlayerResponseButtonCounter].Text = "";
btnPlayerResponse[intPlayerResponseButtonCounter].FlatStyle = FlatStyle.Flat;
btnPlayerResponse[intPlayerResponseButtonCounter].MouseClick += new MouseEventHandler(btnPlayerResponse_Click);
}
Controls.Add(lblInitializing);
lblInitializing.Text = "Initializing data";
lblInitializing.BackColor = Color.Yellow;
lblInitializing.AutoSize = true;
lblInitializing.Left = (Screen.PrimaryScreen.WorkingArea.Width - lblInitializing.Width) / 2;
lblInitializing.Top = proBar.Top + proBar.Height + 5;
lblInitializing.Visible = true;
lblInitializing.BringToFront();
picBoard.BringToFront();
proBar.BringToFront();
lblInitializing.BringToFront();
tmrAutoProceed.Interval = intBaseAutoProceedInterval;
tmrAutoProceed.Tick += new EventHandler(tmrAutoProceed_Tick);
}
bool autoProceedEnabled
{
get { return tmrAutoProceed.Enabled; }
set
{
tmrAutoProceed.Enabled = false;
tmrAutoProceed.Enabled = value;
}
}
void grbSpeed_MouseEnter(object sender, EventArgs e)
{
bolHideOptions = true;
}
void grbSetAI_MouseEnter(object sender, EventArgs e)
{
bolHideOptions = true;
}
void hsbSpeed_ValueChanged(object sender, EventArgs e)
{
double dblMaxFactor = 10;
double dblMinFactor = 0.1;
double dblSlope = (dblMaxFactor - dblMinFactor) / (-(double)hsbSpeed.Maximum);
dblSpeedFactor = dblSlope * (double)hsbSpeed.Value + dblMaxFactor;
tmrAutoProceed.Interval = (int)((double)intBaseAutoProceedInterval * dblSpeedFactor);
}
void chkSpeed_AutoProceed_CheckedChanged(object sender, EventArgs e)
{
bolAutoProceed = chkSpeed_AutoProceed.Checked;
}
void grbSetAI_MouseClick(object sender, MouseEventArgs e)
{
enuSuspects eSuspectMouseOver = getMouseOverAISuspect(new Point(e.X, e.Y));
if (eSuspectMouseOver != enuSuspects._numSuspects)
{
classSuspect cSus = cSuspects[(int)eSuspectMouseOver];
cSus.eAILevel = (enuAILevel)(((int)cSus.eAILevel + 1) % (int)enuAILevel._numAILevels);
drawSuspectAILevel();
}
}
void picNotebook_MouseWheel(object sender, MouseEventArgs e)
{
if (!bolInit)
return;
if (cButtons[(int)enuButtons.MouseOver] != null)
{
if (e.Delta > 0)
cButtons[(int)enuButtons.MouseOver].cNote.Note = (enuNote)(((int)cButtons[(int)enuButtons.MouseOver].cNote.Note - 1 + (int)enuNote._numNotes) % (int)(enuNote._numNotes));
else
cButtons[(int)enuButtons.MouseOver].cNote.Note = (enuNote)(((int)cButtons[(int)enuButtons.MouseOver].cNote.Note + 1) % (int)(enuNote._numNotes));
}
}
void picNotebook_MouseMove(object sender, MouseEventArgs e)
{
if (!bolInit)
return;
Point ptMouse = new Point(e.X, e.Y);
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
{
if (ptMouse.Y > cPlayerNotes[0, (int)eCardCounter].pt.Y && ptMouse.Y < cPlayerNotes[0, (int)eCardCounter].pt.Y + 25)
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
if (ptMouse.X > cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter].pt.X
&& ptMouse.X < cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter].pt.X + 25)
{
classNote cThisNote = cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter];
if (cMouseOverNote != cThisNote)
{
if (cMouseOverNote != null)
cMouseOverNote.draw();
cThisNote.highlight();
cMouseOverNote = cThisNote;
}
return;
}
}
}
}
if (cMouseOverNote != null)
cMouseOverNote.draw();
cMouseOverNote = null;
}
void picNotebook_MouseClick(object sender, MouseEventArgs e)
{
if (!bolInit)
return;
if (cMouseOverNote != null)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
cMouseOverNote.Note = (enuNote)(((int)cMouseOverNote.Note + 1) % (int)(enuNote._numNotes));
else if (e.Button == System.Windows.Forms.MouseButtons.Right)
cMouseOverNote.Note = (enuNote)(((int)cMouseOverNote.Note - 1 + (int)enuNote._numNotes) % (int)(enuNote._numNotes));
cMouseOverNote.highlight();
}
}
void picNotebook_MouseLeave(object sender, EventArgs e)
{
if (!bolInit)
return;
if (cButtons[(int)enuButtons.MouseOver] != null)
cButtons[(int)enuButtons.MouseOver].draw();
}
void picBoard_MouseLeave(object sender, EventArgs e)
{
if (!bolInit)
return;
if (cButtons[(int)enuButtons.MouseOver] != null)
cButtons[(int)enuButtons.MouseOver].draw();
}
void hideOptions()
{
if (bolHideOptions)
{
grbSetAI.Visible = grbSpeed.Visible = false;
bolHideOptions = false;
}
}
void drawSuspectAILevel()
{
Font fnt = new System.Drawing.Font("Blackadder itc", 18);
Bitmap bmpTemp = new Bitmap(Clue_CS2010.Properties.Resources.setAI);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
Bitmap bmpAILevel = getTextImage(cSuspects[(int)eSuspectCounter].eAILevel.ToString(),
fnt,
Color.Black);
bmpAILevel.MakeTransparent();
g.DrawImage(bmpAILevel, ptSetAI[(int)eSuspectCounter]);
}
}
grbSetAI.BackgroundImage = bmpTemp;
}
#region "init objects & classes"
void initSuspects()
{
bmpSuspects[(int)enuSuspects.MissScarlet] = new Bitmap(Clue_CS2010.Properties.Resources.SuspectMissScarlet); bmpSuspects[(int)enuSuspects.MissScarlet].MakeTransparent();
bmpSuspects[(int)enuSuspects.ColMustard] = new Bitmap(Clue_CS2010.Properties.Resources.SuspectColMustard); bmpSuspects[(int)enuSuspects.ColMustard].MakeTransparent();
bmpSuspects[(int)enuSuspects.MrsWhite] = new Bitmap(Clue_CS2010.Properties.Resources.SuspectMrsWhite); bmpSuspects[(int)enuSuspects.MrsWhite].MakeTransparent();
bmpSuspects[(int)enuSuspects.RevGreen] = new Bitmap(Clue_CS2010.Properties.Resources.SuspectRevGreen); bmpSuspects[(int)enuSuspects.RevGreen].MakeTransparent();
bmpSuspects[(int)enuSuspects.MrsPeacock] = new Bitmap(Clue_CS2010.Properties.Resources.SuspectMrsPeacock); bmpSuspects[(int)enuSuspects.MrsPeacock].MakeTransparent();
bmpSuspects[(int)enuSuspects.ProfPlum] = new Bitmap(Clue_CS2010.Properties.Resources.SuspectProfPlum); bmpSuspects[(int)enuSuspects.ProfPlum].MakeTransparent();
cSuspects = new classSuspect[(int)enuSuspects._numSuspects];
for (enuSuspects SuspectCounter = (enuSuspects)0; SuspectCounter < enuSuspects._numSuspects; SuspectCounter++)
cSuspects[(int)SuspectCounter] = new classSuspect(SuspectCounter, this);
}
void initSetAIGroupBox()
{
ptSetAI = new Point[(int)enuSuspects._numSuspects];
ptSetAI[(int)enuSuspects.ColMustard] = new Point(240, 33);
ptSetAI[(int)enuSuspects.ProfPlum] = new Point(240, 59);
ptSetAI[(int)enuSuspects.RevGreen] = new Point(240, 85);
ptSetAI[(int)enuSuspects.MrsPeacock] = new Point(240, 112);
ptSetAI[(int)enuSuspects.MissScarlet] = new Point(240, 138);
ptSetAI[(int)enuSuspects.MrsWhite] = new Point(240, 164);
drawSuspectAILevel();
}
void initWeapons()
{
bmpWeapons_PicTray[(int)enuWeapons.Candlestick] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponCandlestick);
bmpWeapons_PicTray[(int)enuWeapons.Knife] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponKnife);
bmpWeapons_PicTray[(int)enuWeapons.LeadPipe] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponLeadPipe);
bmpWeapons_PicTray[(int)enuWeapons.Revolver] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponRevolver);
bmpWeapons_PicTray[(int)enuWeapons.Rope] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponRope);
bmpWeapons_PicTray[(int)enuWeapons.Wrench] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponWrench);
cWeapons = new classWeapon[(int)enuWeapons._numWeapons];
for (enuWeapons eWeaponCounter = (enuWeapons)0; eWeaponCounter < enuWeapons._numWeapons; eWeaponCounter++)
cWeapons[(int)eWeaponCounter] = new classWeapon(eWeaponCounter);
bmpWeapons_Board = new Bitmap[(int)enuWeapons._numWeapons];
bmpWeapons_Board[(int)enuWeapons.Candlestick] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponBoard_Candlestick); bmpWeapons_Board[(int)enuWeapons.Candlestick].MakeTransparent(bmpWeapons_Board[(int)enuWeapons.Candlestick].GetPixel(0, 0));
bmpWeapons_Board[(int)enuWeapons.Knife] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponBoard_Knife); bmpWeapons_Board[(int)enuWeapons.Knife].MakeTransparent(bmpWeapons_Board[(int)enuWeapons.Knife].GetPixel(0, 0));
bmpWeapons_Board[(int)enuWeapons.LeadPipe] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponBoard_LeadPipe); bmpWeapons_Board[(int)enuWeapons.LeadPipe].MakeTransparent(bmpWeapons_Board[(int)enuWeapons.LeadPipe].GetPixel(0, 0));
bmpWeapons_Board[(int)enuWeapons.Revolver] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponBoard_Revolver); bmpWeapons_Board[(int)enuWeapons.Revolver].MakeTransparent(bmpWeapons_Board[(int)enuWeapons.Revolver].GetPixel(0, 0));
bmpWeapons_Board[(int)enuWeapons.Rope] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponBoard_Rope); bmpWeapons_Board[(int)enuWeapons.Rope].MakeTransparent(bmpWeapons_Board[(int)enuWeapons.Rope].GetPixel(0, 0));
bmpWeapons_Board[(int)enuWeapons.Wrench] = new Bitmap(Clue_CS2010.Properties.Resources.WeaponBoard_Wrench); bmpWeapons_Board[(int)enuWeapons.Wrench].MakeTransparent(bmpWeapons_Board[(int)enuWeapons.Wrench].GetPixel(0, 0));
}
void initRooms()
{
cRooms = new classRoom[(int)enuRooms._numRooms];
for (enuRooms eRoomCounter = (enuRooms)0; eRoomCounter < enuRooms._numRooms; eRoomCounter++)
cRooms[(int)eRoomCounter] = new classRoom(eRoomCounter, this);
bmpRooms[(int)enuRooms.BallRoom] = Clue_CS2010.Properties.Resources.CrimeSceneBallRoom;
bmpRooms[(int)enuRooms.BilliardRoom] = Clue_CS2010.Properties.Resources.CrimeSceneBilliardRoom;
bmpRooms[(int)enuRooms.Conservatory] = Clue_CS2010.Properties.Resources.CrimeSceneConservatory;
bmpRooms[(int)enuRooms.DiningRoom] = Clue_CS2010.Properties.Resources.CrimeSceneDiningRoom;
bmpRooms[(int)enuRooms.Hall] = Clue_CS2010.Properties.Resources.CrimeSceneHall;
bmpRooms[(int)enuRooms.Kitchen] = Clue_CS2010.Properties.Resources.CrimeSceneKitchen;
bmpRooms[(int)enuRooms.Library] = Clue_CS2010.Properties.Resources.CrimeSceneLibrary;
bmpRooms[(int)enuRooms.Lounge] = Clue_CS2010.Properties.Resources.CrimeSceneLounge;
bmpRooms[(int)enuRooms.Study] = Clue_CS2010.Properties.Resources.CrimeSceneStudy;
}
void initColors()
{
clrSuspects = new Color[(int)enuSuspects._numSuspects];
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
clrSuspects[(int)eSuspectCounter] = bmpPieces[(int)eSuspectCounter].GetPixel(5, 5);
}
void initPieces()
{
bmpPieces[(int)enuSuspects.MissScarlet] = new Bitmap(Clue_CS2010.Properties.Resources.Piece_MissScarlet); bmpPieces[(int)enuSuspects.MissScarlet].MakeTransparent();
bmpPieces[(int)enuSuspects.ColMustard] = new Bitmap(Clue_CS2010.Properties.Resources.Piece_ColMustard); bmpPieces[(int)enuSuspects.ColMustard].MakeTransparent();
bmpPieces[(int)enuSuspects.MrsWhite] = new Bitmap(Clue_CS2010.Properties.Resources.Piece_MrsWhite); bmpPieces[(int)enuSuspects.MrsWhite].MakeTransparent();
bmpPieces[(int)enuSuspects.RevGreen] = new Bitmap(Clue_CS2010.Properties.Resources.Piece_RevGreen); bmpPieces[(int)enuSuspects.RevGreen].MakeTransparent();
bmpPieces[(int)enuSuspects.MrsPeacock] = new Bitmap(Clue_CS2010.Properties.Resources.Piece_MrsPeacock); bmpPieces[(int)enuSuspects.MrsPeacock].MakeTransparent();
bmpPieces[(int)enuSuspects.ProfPlum] = new Bitmap(Clue_CS2010.Properties.Resources.Piece_ProfPlum); bmpPieces[(int)enuSuspects.ProfPlum].MakeTransparent();
}
//void initIntroMice()
//{
// cBmpDie = new classRotatedImage[3];
// string strDirectoryAndBaseDieFilename = System.IO.Directory.GetCurrentDirectory() + "\\mouse";
// for (int intMouseTailCounter = 0; intMouseTailCounter < 3; intMouseTailCounter++)
// {
// cBmpDie[intMouseTailCounter] = new classRotatedImage();
// string strThisDieFilename = strDirectoryAndBaseDieFilename + intMouseTailCounter.ToString() + ".rBMP";
// if (System.IO.File.Exists(strThisDieFilename))
// {
// cBmpDie[intMouseTailCounter].loadBaseImages(strThisDieFilename);
// }
// else
// {
// Pen pWhite = new Pen(Color.White, 2);
// Bitmap bmpOriginal = Clue_CS2010.Properties.Resources.Mouse00;
// switch (intMouseTailCounter)
// {
// case 1:
// bmpOriginal = Clue_CS2010.Properties.Resources.Mouse01;
// break;
// case 2:
// bmpOriginal = Clue_CS2010.Properties.Resources.Mouse02;
// break;
// }
// cBmpDie[intMouseTailCounter].createBaseImage(bmpOriginal);
// cBmpDie[intMouseTailCounter].saveBaseImages(strThisDieFilename);
// }
// }
//}
void initDieImages()
{
cBmpDie = new classRotatedImage[7];
string strDirectoryAndBaseDieFilename = System.IO.Directory.GetCurrentDirectory() + "\\die";
for (int intDieValueCounter = 1; intDieValueCounter < 7; intDieValueCounter++)
{
cBmpDie[intDieValueCounter] = new classRotatedImage();
string strThisDieFilename = strDirectoryAndBaseDieFilename + intDieValueCounter.ToString() + ".rBMP";
if (System.IO.File.Exists(strThisDieFilename))
{
cBmpDie[intDieValueCounter].loadBaseImages(strThisDieFilename);
}
else
{
Pen pWhite = new Pen(Color.White, 2);
Bitmap bmpOriginal = Clue_CS2010.Properties.Resources.die1;
switch (intDieValueCounter)
{
case 2:
bmpOriginal = Clue_CS2010.Properties.Resources.die2;
break;
case 3:
bmpOriginal =Clue_CS2010.Properties.Resources.die3;
break;
case 4:
bmpOriginal =Clue_CS2010.Properties.Resources.die4;
break;
case 5:
bmpOriginal =Clue_CS2010.Properties.Resources.die5;
break;
case 6:
bmpOriginal =Clue_CS2010.Properties.Resources.die6;
break;
}
cBmpDie[intDieValueCounter].createBaseImage(bmpOriginal);
cBmpDie[intDieValueCounter].saveBaseImages(strThisDieFilename);
}
}
}
void initCards()
{
cCards = new classCard[(int)enuCards._numCards];
for (enuCards cardCounter = (enuCards)0; cardCounter < enuCards._numCards; cardCounter++)
{
cCards[(int)cardCounter] = new classCard(this, cardCounter);
}
cCardUnknown = new classCard(this, enuCards.Unknown);
}
void initMenu()
{
ToolStripMenuItem mnuFile = new ToolStripMenuItem();
mnuFile.Text = "&File";
mnuFile.DropDownItems.Add("&New Game", null, NewGame);
mnuFile.DropDownItems.Add("E&xit", null, Exit);
mnu.Items.Add(mnuFile);
Controls.Add(mnu);
ToolStripMenuItem mnuOptions = new ToolStripMenuItem();
mnuOptions.Text = "&Options";
mnuOptions.DropDownItems.Add("set &AI", null, SetAI);
mnuOptions.DropDownItems.Add("&Speed", null, SetSpeed);
mnu.Items.Add(mnuOptions);
Controls.Add(mnu);
ToolStripMenuItem mnuHelp = new ToolStripMenuItem();
mnuHelp.Text = "&Help";
mnuHelp.Click +=new EventHandler(Instructions);
mnu.Items.Add(mnuHelp);
Controls.Add(mnu);
mnu.BackColor = Color.Black;
mnu.ForeColor = Color.White;
mnu.Visible = true;
}
#endregion
void Instructions(object sender, EventArgs e)
{
if (frmInstructions == null)
frmInstructions = new formInstructions();
frmInstructions.ShowDialog();
frmInstructions.Width = (int)(Screen.PrimaryScreen.WorkingArea.Width * .7);
frmInstructions.Height = (int)(Screen.PrimaryScreen.WorkingArea.Height * .7);
frmInstructions.Left = (Screen.PrimaryScreen.WorkingArea.Width - frmInstructions.Width) / 2;
frmInstructions.Top = (Screen.PrimaryScreen.WorkingArea.Height - frmInstructions.Height) / 2;
}
void SetSpeed(object sender, EventArgs e)
{
grbSpeed.Visible = !grbSpeed.Visible;
}
void SetAI(object sender, EventArgs e)
{
grbSetAI.Visible = !grbSetAI.Visible;
}
void Exit(object sender, EventArgs e)
{
Dispose();
}
public void setUpCLibPicTrayChooseWeapon()
{
setPicTrayBackgroundImage(ref cLibPicTrayWeapons);
cLibPicTrayWeapons.Visible = true;
cLibPicTrayWeapons.BringToFront();
cLibPicTrayWeapons.RefreshTrayImage();
bringControlsUpFront();
}
void bringControlsUpFront()
{
grbSetAI.BringToFront();
grbSpeed.BringToFront();
}
void setUpCLibPicTrayChooseSuspect()
{
setPicTrayBackgroundImage(ref cLibPicTraySuspects);
cLibPicTraySuspects.Visible = true;
cLibPicTraySuspects.BringToFront();
cLibPicTraySuspects.RefreshTrayImage();
bringControlsUpFront();
}
public void NewGame(object sender, EventArgs e)
{
eMode = enuMode.chooseCharacter; eDealMode = (enuDealCardsMode)0;
btnAccuse.Text = "Accuse";
btnAccuse.Enabled = false;
intNumTurns = 1;
cLibPicTrayRooms.Visible =
cLibPicTrayWeapons.Visible = false;
bolDisableMouseClickBoard = false;
btnChooseSuspect.Location = new Point(260, 530);
bmpDealAnimationBoard_Base = AnimateDealCards_getBlankDealCardsImage();
picBoard.Size = bmpDealAnimationBoard_Base.Size;
picBoard.Image = bmpDealAnimationBoard_Base;
picBoard.BringToFront();
Bitmap bmpChooseSuspect = new Bitmap(btnChooseSuspect.Width, btnChooseSuspect.Height);
using (Graphics g = Graphics.FromImage(bmpChooseSuspect))
{
Rectangle recSrc = new Rectangle(btnChooseSuspect.Location.X, btnChooseSuspect.Location.Y - 25, btnChooseSuspect.Size.Width, btnChooseSuspect.Size.Height);
Rectangle recDest = new Rectangle(0, 0, btnChooseSuspect.Width, btnChooseSuspect.Height);
g.DrawImage(new Bitmap(bmpBoard), recDest, recSrc, GraphicsUnit.Pixel);
}
btnChooseSuspect.BackgroundImage = bmpChooseSuspect;
#region "cLibPicTraySuspects Choose Player Character"
cLibPicTraySuspects.Location = new Point(0, 0);
cLibPicTraySuspects.Options.Mirror = PicTray.enuMirror.none;
cLibPicTraySuspects.Options.makeImagesTransparent = true;
cLibPicTraySuspects.Options.PopUpClickPic = false;
cLibPicTraySuspects.Options.SelectionMode = PicTray.enuSelectionMode.click;
cLibPicTraySuspects.Options.TrayCenter = new Point(351, 182);
cLibPicTraySuspects.Options.Width = 711;
cLibPicTraySuspects.Options.Height = 491;
cLibPicTraySuspects.Options.Rotation.StepSize = 0.119380520836412;
cLibPicTraySuspects.Options.Rotation.Interval = 27;
cLibPicTraySuspects.Options.Rotation.Mode = PicTray.enuRotationMode.toSelected;
cLibPicTraySuspects.Options.Ellipse.Angle = 0;
cLibPicTraySuspects.Options.Ellipse.Radius_Height = 124;
cLibPicTraySuspects.Options.Ellipse.Radius_Width = 280;
cLibPicTraySuspects.Options.Front.Angle = 1.56765473414131;
cLibPicTraySuspects.Options.Front.UserSet = PicTray.enuFrontUserSet.none;
cLibPicTraySuspects.Options.ImageSize.Height_MinMax = new PicTray.classMinMax(35, 343);
cLibPicTraySuspects.Options.ImageSize.Width_MinMax = new PicTray.classMinMax(35, 300);
cLibPicTraySuspects.Options.Caption.Show = false;
cLibPicTraySuspects.Options.Caption.Font = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
cLibPicTraySuspects.Options.Caption.ForeColor = Color.FromArgb(255, 255, 255, 0);
cLibPicTraySuspects.Options.Caption.BackColor = Color.FromArgb(255, 0, 0, 0);
#endregion
resetSuspects(enuSuspects.MissScarlet);
resetPlayerNotes();
btnWarnPlayerWhoseTurnItIs.Visible = false;
setBtnChooseSuspectColorAndText();
setUpCLibPicTrayChooseSuspect();
btnChooseSuspect.Visible = true;
btnChooseSuspect.BringToFront();
bringControlsUpFront();
}
void resetPlayerNotes()
{
bmpNotebook = new Bitmap(Clue_CS2010.Properties.Resources.notebook);
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
if (cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter] == null)
cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter] = new classNote( this,
ref picNotebook,
enuMode.any,
eSuspectCounter,
eCardCounter);
cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter].Note = enuNote.blank;
cPlayerNotes[(int)eSuspectCounter, (int)eCardCounter].setMyImages();
}
picNotebook.Image = bmpNotebook;
picNotebook.Refresh();
}
void setAccusation()
{
udrSuggestion.eRoom = (enuRooms)cLibPicTrayRooms.SelectedImage.Index;
udrSuggestion.eSuspect = cSuspects[cLibPicTraySuspects.SelectedImage.Index].eName;
udrSuggestion.eWeapon = (enuWeapons)cLibPicTrayWeapons.SelectedImage.Index;
btnAccuse_Ok.Text = "I accuse " + udrSuggestion.eSuspect.ToString()
+ "\r\n" + " in the " + udrSuggestion.eRoom.ToString()
+ "\r\n" + " with the " + udrSuggestion.eWeapon.ToString();
Bitmap bmpAccuseButton = new Bitmap(btnAccuse_Ok.Width, btnAccuse_Ok.Height);
using (Graphics g = Graphics.FromImage(bmpAccuseButton))
{
// draw suspects' tray image top-left corner of button
Rectangle recSrc = new Rectangle(btnAccuse_Ok.Location.X, btnAccuse_Ok.Location.Y, cLibPicTraySuspects.Width - btnAccuse_Ok.Left, cLibPicTraySuspects.Height - btnAccuse_Ok.Top);
Rectangle recDest = new Rectangle(0, 0, recSrc.Width, recSrc.Height);
g.DrawImage(new Bitmap(cLibPicTraySuspects.Image), recDest, recSrc, GraphicsUnit.Pixel);
// draw weapons' tray image top-right corner of button
recSrc = new Rectangle(0, btnAccuse_Ok.Location.Y, btnAccuse_Ok.Width + btnAccuse_Ok.Left - cLibPicTrayWeapons.Left, cLibPicTrayWeapons.Height - btnAccuse_Ok.Top);
recDest = new Rectangle(cLibPicTrayWeapons.Left - btnAccuse_Ok.Left, 0, recSrc.Width , recSrc.Height);
g.DrawImage(new Bitmap(cLibPicTrayWeapons.Image), recDest, recSrc, GraphicsUnit.Pixel);
// draw rooms' tray image bottom half of button
recSrc = new Rectangle(btnAccuse_Ok.Left, 0, btnAccuse_Ok.Width, btnAccuse_Ok.Top + btnAccuse_Ok.Height - cLibPicTrayRooms.Top);
recDest = new Rectangle(0, cLibPicTrayRooms.Top - btnAccuse_Ok.Top, recSrc.Width, recSrc.Height);
g.DrawImage(new Bitmap(cLibPicTrayRooms.Image), recDest, recSrc, GraphicsUnit.Pixel);
}
btnAccuse_Ok.BackgroundImage = bmpAccuseButton;
btnAccuse_Ok.BringToFront();
btnAccuse_Ok.Visible = true;
}
void setSuggestion()
{
bool bolRefreshSuggestionImage = false;
if (udrSuggestion.eRoom != cSuspects[intSuspectTurn].eRoom)
{
udrSuggestion.eRoom = cSuspects[intSuspectTurn].eRoom;
bolRefreshSuggestionImage = true;
}
if (udrSuggestion.eSuspect != cSuspects[cLibPicTraySuspects.SelectedImage.Index].eName)
{
udrSuggestion.eSuspect = cSuspects[cLibPicTraySuspects.SelectedImage.Index].eName;
bolRefreshSuggestionImage = true;
}
if (udrSuggestion.eWeapon != (enuWeapons)cLibPicTrayWeapons.SelectedImage.Index)
{
udrSuggestion.eWeapon = (enuWeapons)cLibPicTrayWeapons.SelectedImage.Index;
bolRefreshSuggestionImage = true;
}
if (bolRefreshSuggestionImage)
writeSuggestion();
}
void writeResponse(enuCards eCard_response, enuSuspects eSuspect_responding)
{
Bitmap bmpNewBoard = new Bitmap(picBoard.Image);
using (Graphics g = Graphics.FromImage(bmpNewBoard))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(ptResponseBubbleTL.X + 14, ptResponseBubbleTL.Y + 9, 330, 55));
Bitmap bmpText;
Font fnt = new System.Drawing.Font("blackadder itc", 36);
Rectangle recDest, recSrc;
if (eCard_response == enuCards.NoCardShown)
{
bmpText = getTextImage("Sorry, no card", fnt, Color.Black);
recDest = new Rectangle(ptResponseBubbleTL.X + 25, ptResponseBubbleTL.Y + 15, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
}
else
{
bmpText = getTextImage("I have a card", fnt, Color.Black);
recDest = new Rectangle(ptResponseBubbleTL.X + 25, ptResponseBubbleTL.Y + 15, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
Bitmap bmpCardShow = bmpCardBack;
if (cSuspects[intSuspectTurn].bolPlayerControlled || eSuspect_responding == getPlayerSuspect().eName)
{
bmpCardShow = cCards[(int)eCard_response].cBmp.getImage(0);
}
int intWidth = 120;
recDest = new Rectangle(287, ptResponseBubbleTL.Y + bmpResponseBubble.Height, intWidth, (int)((double)bmpCardShow.Height / (double)bmpCardShow.Width * intWidth));
recSrc = new Rectangle(0, 0, bmpCardShow.Width, bmpCardShow.Height);
g.DrawImage(bmpCardShow, recDest, recSrc, GraphicsUnit.Pixel);
}
}
picBoard.Image = bmpNewBoard; picBoard.Refresh();
}
void writeSuggestion()
{
Bitmap bmpNewBoard = new Bitmap(picBoard.Image);
using (Graphics g = Graphics.FromImage(bmpNewBoard))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(ptSuggestionBubbleTL.X + 54, ptSuggestionBubbleTL.Y + 9, 335, 280));
Bitmap bmpText;
Font fnt = new System.Drawing.Font("blackadder itc", 36);
Rectangle recDest, recSrc;
int intTop = 0;
int intVLineSpacine = 45;
int intLeftText = 50;
int intTabText = 140;
bmpText = getTextImage("I suggest", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(udrSuggestion.eSuspect.ToString(), fnt, udrSuggestion.eSuspect == enuSuspects.MrsWhite ? Color.Gray : clrSuspects[(int)udrSuggestion.eSuspect]);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intTabText, ptSuggestionBubbleTL.Y + intTop + intVLineSpacine + 10, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage("in the", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop + 2 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(udrSuggestion.eRoom.ToString(), fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intTabText, ptSuggestionBubbleTL.Y + intTop + 3 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage("with the", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop + 4 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(udrSuggestion.eWeapon.ToString(), fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intTabText, ptSuggestionBubbleTL.Y + intTop + 5 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
}
picBoard.Image = bmpNewBoard;
}
void setBtnChooseSuspectColorAndText()
{
btnChooseSuspect.PulseColor =
btnChooseSuspect.ButtonColorTop = clrSuspects[cLibPicTraySuspects.SelectedImage.Index];
btnChooseSuspect.ButtonColorBottom = Color.FromArgb((btnChooseSuspect.ButtonColorTop.A + 127) % 255,
(btnChooseSuspect.ButtonColorTop.R + 127) % 255,
(btnChooseSuspect.ButtonColorTop.G + 127) % 255,
(btnChooseSuspect.ButtonColorTop.B + 127) % 255);
btnChooseSuspect.Text = "Play as " + cLibPicTraySuspects.SelectedImage.caption;
}
void btnChooseSuspect_Click(object sender, EventArgs e)
{
int intPlayerCharacter = cLibPicTraySuspects.SelectedImage.Index;
resetSuspects(cSuspects[intPlayerCharacter].eName);
resetWeapons();
commitMurder();
dealCards();
eMode = enuMode.dealCards;
}
void setSuspectsAI()
{
for (int intSuspectCounter = 0; intSuspectCounter < cSuspects.Length; intSuspectCounter++)
{
if (!cSuspects[intSuspectCounter].bolPlayerControlled)
{
cSuspects[intSuspectCounter].setAI();
}
}
}
void eraseDie()
{
picDieBox.Image = new Bitmap(bmpBaize);
}
public void nextPlayer()
{
tmrNextPlayer.Enabled = true;
}
void tmrNextPlayer_Tick(object sender, EventArgs e)
{
tmrNextPlayer.Enabled = false;
_nextPlayer();
}
void _nextPlayer()
{
btnEndTurn.Enabled = false;
btnAccuse.Text = "Accuse";
eraseDie();
cSuspects[intSuspectTurn].resetAllowableMoves(); drawBoard();
do
{
intSuspectTurn = (intSuspectTurn + 1) % 6;
} while (cSuspects[intSuspectTurn].bolEliminated);
cSuspects[intSuspectTurn].bolMustMove = true;
if (intSuspectTurn == 0)
{
intNumTurns++;
}
btnRollDie.Enabled = true;
btnSuggest.Enabled = cSuspects[intSuspectTurn].bolCanSuggest;
cSuspects[intSuspectTurn].bolHasNotYetMadeASuggestionThisTurn = true;
cSuspects[intSuspectTurn].resetAllowableMoves();
eMode = enuMode.warnPlayerNextTurn;
}
void eraseWarnPlayerWhoseTurnItIs()
{
Bitmap bmpTemp = new Bitmap(picBoard.Width, picBoard.Height);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.DrawImage(bmpGameBoard, new Point(0, 0));
g.DrawImage(new Bitmap(picNotebook.Image), new Point(bmpBoard.Width + 5, 0));
}
picBoard.Image = bmpTemp; picBoard.Refresh();
}
void warnPlayerWhoseTurnItIs()
{
btnAccuse.Enabled = false;
double dblSizeDifference = 1.5;
Size szNewPicFrame = new System.Drawing.Size((int)(Clue_CS2010.Properties.Resources.picture_frame_oval.Width * dblSizeDifference),
(int)(Clue_CS2010.Properties.Resources.picture_frame_oval.Height * dblSizeDifference));
Bitmap bmpPicFrame = new Bitmap(Clue_CS2010.Properties.Resources.picture_frame_oval, szNewPicFrame);
Color clrBack = bmpPicFrame.GetPixel(0, 0);
Color clrMirror = bmpPicFrame.GetPixel(bmpPicFrame.Width / 2, bmpPicFrame.Height / 2);
bmpPicFrame.MakeTransparent(clrMirror);
Bitmap bmpSuspectImage = new Bitmap(bmpPicFrame.Width, bmpPicFrame.Height);
using (Graphics g = Graphics.FromImage(bmpSuspectImage))
{
int intHeight = (int)(.8 * bmpPicFrame.Height); // controls the size of the output image relative to original
Rectangle recDest = new Rectangle((bmpPicFrame.Width - intHeight) / 2, (int)((bmpPicFrame.Height - intHeight) * .6), intHeight, intHeight);
Rectangle recSrc = new Rectangle(0, 0, bmpSuspects[intSuspectTurn].Width, bmpSuspects[intSuspectTurn].Height);
g.DrawImage(bmpSuspects[intSuspectTurn], recDest, recSrc, GraphicsUnit.Pixel);
g.DrawImage(bmpPicFrame, new Point(0, 0));
}
bmpSuspectImage.MakeTransparent(clrBack);
Bitmap bmpTemp = new Bitmap(picBoard.Width, picBoard.Height);
Point ptLocPicFrame = new Point((Screen.PrimaryScreen.WorkingArea.Width - bmpSuspectImage.Width) / 2, 100);
// if screen is so wide that mid-screen off the bitmap, adjust
if (ptLocPicFrame.X > bmpTemp.Width - bmpSuspectImage.Width / 2)
ptLocPicFrame.X = bmpTemp.Width - bmpSuspectImage.Width / 2;
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.DrawImage(new Bitmap(picBoard.Image), new Point(0, 0));
g.DrawImage(new Bitmap(picNotebook.Image), new Point(pnlNotebook.Left, 0));
g.DrawImage(bmpSuspectImage, new Rectangle(ptLocPicFrame, szNewPicFrame), new Rectangle(new Point(0, 0), new Size(szNewPicFrame.Width - 1, szNewPicFrame.Height - 1)), GraphicsUnit.Pixel);
}
picBoard.BringToFront();
picBoard.Image = bmpTemp; picBoard.Refresh();
picBoard.Width = ptLocPicFrame.X + szNewPicFrame.Width + 10;
if (cSuspects[intSuspectTurn].bolPlayerControlled)
{
btnWarnPlayerWhoseTurnItIs.AutoSize = true;
btnWarnPlayerWhoseTurnItIs.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly;
btnWarnPlayerWhoseTurnItIs.PulseColor =
btnWarnPlayerWhoseTurnItIs.ButtonColorTop = clrSuspects[intSuspectTurn];
btnWarnPlayerWhoseTurnItIs.ButtonColorBottom = Color.FromArgb((btnWarnPlayerWhoseTurnItIs.ButtonColorTop.A + 127) % 255,
(btnWarnPlayerWhoseTurnItIs.ButtonColorTop.R + 127) % 255,
(btnWarnPlayerWhoseTurnItIs.ButtonColorTop.G + 127) % 255,
(btnWarnPlayerWhoseTurnItIs.ButtonColorTop.B + 127) % 255);
btnWarnPlayerWhoseTurnItIs.Text = "Your turn " + cSuspects[intSuspectTurn].eName.ToString();
btnWarnPlayerWhoseTurnItIs.Location = new Point(ptLocPicFrame.X + bmpPicFrame.Width / 2 - btnWarnPlayerWhoseTurnItIs.Width / 2,
ptLocPicFrame.Y + bmpPicFrame.Height + 50);
Bitmap bmpButton = new Bitmap(btnWarnPlayerWhoseTurnItIs.Width, btnWarnPlayerWhoseTurnItIs.Height);
using (Graphics g = Graphics.FromImage(bmpButton))
{
Rectangle recDest = new Rectangle(0, 0, bmpButton.Width, bmpButton.Height);
Rectangle recSrc = new Rectangle(btnWarnPlayerWhoseTurnItIs.Left, btnWarnPlayerWhoseTurnItIs.Top - picBoard.Top, bmpButton.Width, bmpButton.Height);
g.DrawImage(bmpTemp, recDest, recSrc, GraphicsUnit.Pixel);
}
btnWarnPlayerWhoseTurnItIs.BackgroundImage = bmpButton;
btnWarnPlayerWhoseTurnItIs.Visible = true; btnWarnPlayerWhoseTurnItIs.BringToFront();
}
else
setDelayTimer(3000);
bringControlsUpFront();
}
string shuffleCards() { return shuffleCards(true); }
string shuffleCards(bool bolExcludeMurderCards)
{
string strCards = "";
int intNumSuspects = (int)enuSuspects._numSuspects;
int intNumSuspectsAndWeapons = intNumSuspects + (int)enuWeapons._numWeapons;
enuCards eWeapon = classCard.getECardFromEWeapon( udrMurder.eWeapon);
enuCards eSuspect = classCard.getECardFromESuspect(udrMurder.eSuspect);
enuCards eRoom = classCard.getECardFromERoom(udrMurder.eRoom);
// gather cards in string
for (enuCards eCardCounter = 0; eCardCounter < enuCards._numCards; eCardCounter++)
{
// Suspects + weapons + rooms
if (bolExcludeMurderCards
&&
(eCardCounter == eWeapon
|| eCardCounter == eSuspect
|| eCardCounter == eRoom))
{
goto skipAddCard;
}
// add card to string
strCards += ((int)eCardCounter).ToString("d2");
skipAddCard: ;
}
// shuffle cards
int intNumCards = strCards.Length / 2;
for (int intShuffleCounter = 0; intShuffleCounter < 10000; intShuffleCounter++)
{
int intA = 0, intB = 0;
while (intA >= intB)
{
intA = (int)(rnd.NextDouble() * 1000) % intNumCards;
intB = (int)(rnd.NextDouble() * 1000) % intNumCards;
}
string strA = strCards.Substring(0, intA * 2);
string strB = strCards.Substring(strA.Length, (intB - intA) * 2);
string strC = strCards.Substring(strA.Length + strB.Length);
strCards = strC + strB + strA;
}
return strCards;
}
void dealCards()
{
string strCards = strCardsDealt = shuffleCards();
// deal cards
enuSuspects eSuspectCounter = (enuSuspects)0;
while (strCards.Length > 0)
{
string strThisCard = strCards.Substring(0, 2);
strCards = strCards.Substring(2);
int intThisCard = Convert.ToInt16(strThisCard);
classCard thisCard = cCards[intThisCard];
cSuspects[(int)eSuspectCounter].receiveCard(ref thisCard);
eSuspectCounter = (enuSuspects)(((int)eSuspectCounter + 1) % (int)enuSuspects._numSuspects);
}
}
void setPlayerNoteBook()
{
classSuspect cPlayer = getPlayerSuspect();
for (int intCardCounter = 0; intCardCounter < cPlayer.cCards.Length; intCardCounter++)
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
enuNote eNewNote = enuNote.X;
if (cSuspects[(int)eSuspectCounter] == cPlayer)
eNewNote = enuNote.check;
if (cPlayerNotes[(int)cSuspects[(int)eSuspectCounter].eName, (int)cPlayer.cCards[intCardCounter].eCardName].Note != eNewNote)
{
cPlayerNotes[(int)cSuspects[(int)eSuspectCounter].eName, (int)cPlayer.cCards[intCardCounter].eCardName].Note = eNewNote;
}
cPlayerNotes[(int)cSuspects[(int)eSuspectCounter].eName, (int)cPlayer.cCards[intCardCounter].eCardName].draw();
}
}
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
{
if (cPlayerNotes[(int)cPlayer.eName, (int)eCardCounter].Note != enuNote.check)
cPlayerNotes[(int)cPlayer.eName, (int)eCardCounter].Note = enuNote.X;
cPlayerNotes[(int)cSuspects[(int)cPlayer.eName].eName, (int)eCardCounter].draw();
}
}
void commitMurder()
{
udrMurder.eSuspect = (enuSuspects)((int)(rnd.NextDouble() * 10000) % (int)enuSuspects._numSuspects);
udrMurder.eRoom = (enuRooms)((int)(rnd.NextDouble() * 10000) % (int)enuRooms._numRooms);
udrMurder.eWeapon = (enuWeapons)((int)(rnd.NextDouble() * 10000) % (int)enuWeapons._numWeapons);
}
void resetWeapons()
{
for (enuWeapons eWeaponsCounter = (enuWeapons)0; eWeaponsCounter < enuWeapons._numWeapons; eWeaponsCounter++)
cWeapons[(int)eWeaponsCounter].eRoom = enuRooms._numRooms;
}
void resetSuspects(enuSuspects ePlayerCharacter)
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
cSuspects[(int)eSuspectCounter].bolCanSuggest = false;
cSuspects[(int)eSuspectCounter].bolEliminated = false;
cSuspects[(int)eSuspectCounter].bolMustMove = true;
cSuspects[(int)eSuspectCounter].bolPlayerControlled = (eSuspectCounter == ePlayerCharacter);
cSuspects[(int)eSuspectCounter].cCards = new classCard[0];
cSuspects[(int)eSuspectCounter].eRoom = enuRooms.start;
cSuspects[(int)eSuspectCounter].resetAllowableMoves();
cSuspects[(int)eSuspectCounter].initNotes();
}
}
#region "Accusation"
private void btnAccuse_Click(object sender, EventArgs e)
{
if (cSuspects[intSuspectTurn].bolPlayerControlled && !cSuspects[intSuspectTurn].bolEliminated)
{
if (eMode != enuMode.Accuse)
{
udrAniAccusation.eRestoreMode = eMode;
eMode = enuMode.Accuse;
btnAccuse.Text = "cancel Accuse";
}
else
{
eMode = udrAniAccusation.eRestoreMode;
btnAccuse_Ok.Visible =
cLibPicTrayWeapons.Visible =
cLibPicTrayRooms.Visible =
cLibPicTraySuspects.Visible = false;
btnAccuse.Text = "Accuse";
pnlControls.Enabled = true;
}
}
}
public void btnAccuse_Ok_Click(object sender, EventArgs e)
{
udtMurder udrAccusation;
udrAccusation.eWeapon = (enuWeapons)cLibPicTrayWeapons.SelectedImage.Index;
udrAccusation.eSuspect = (enuSuspects)cLibPicTraySuspects.SelectedImage.Index;
udrAccusation.eRoom = (enuRooms)cLibPicTrayRooms.SelectedImage.Index;
btnAccuse.Enabled
= cLibPicTrayRooms.Visible
= cLibPicTrayRooms.tmrRotate.Enabled
= cLibPicTrayWeapons.Visible
= cLibPicTrayWeapons.tmrRotate.Enabled
= cLibPicTraySuspects.Visible
= cLibPicTraySuspects.tmrRotate.Enabled
= btnAccuse_Ok.Visible
= false;
Accuse(getPlayerSuspect().eName, udrAccusation);
}
void animateAccusation()
{
switch (udrAniAccusation._eMode)
{
case enuAccuseAnimationMode.drawAccusation:
AnimateAccusation_drawAccusation();
break;
case enuAccuseAnimationMode.prepareToShowCards:
AnimateAccusation_PrepareToShowCards();
break;
case enuAccuseAnimationMode.showCards:
AnimateAccusation_ShowCards();
break;
case enuAccuseAnimationMode.hideCards:
AnimateAccusation_HideCards();
break;
case enuAccuseAnimationMode.retractCards:
AnimateAccusation_RetractCards();
break;
case enuAccuseAnimationMode.withdrawAccusingSuspect:
AnimateAccusation_WithdrawAccusingSuspect();
break;
case enuAccuseAnimationMode.showNewspaper:
AnimateAccusation_ShowNewspaper();
break;
}
}
void AnimateAccusation_ShowNewspaper()
{
if (!udrAniAccusation.bolInit)
{
udrAniAccusation.intAnimationStep = 0;
udrAniAccusation.udrElements = new udtAnimationInfo[2];
// Murderer's face (index = 0)
udrAniAccusation.udrElements[0].bmp = new Bitmap(bmpSuspects[(int)udrMurder.eSuspect].Width, bmpSuspects[(int)udrMurder.eSuspect].Height);
// need to remove trim color around circular image
Color clrTransparent = bmpSuspects[(int)udrMurder.eSuspect].GetPixel(bmpSuspects[(int)udrMurder.eSuspect].Width / 2, 0);
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[0].bmp))
{
g.FillRectangle(new SolidBrush(clrTransparent), new Rectangle(0, 0, udrAniAccusation.udrElements[0].bmp.Width, udrAniAccusation.udrElements[0].bmp.Height));
g.DrawImage(bmpSuspects[(int)udrMurder.eSuspect], new Point(0, 0));
}
udrAniAccusation.udrElements[0].bmp.MakeTransparent(udrAniAccusation.udrElements[0].bmp.GetPixel(0,0));
int intImageSize = 200;
udrAniAccusation.udrElements[0].dblSizeFactor = (double)intImageSize / (double)udrAniAccusation.udrElements[0].bmp.Width;
int intStartTop = (int)(intImageSize * .55);
udrAniAccusation.udrElements[0].ptPos=
udrAniAccusation.udrElements[0].ptStart = new Point((int)(bmpBoard.Width * .5), intStartTop + 20);
udrAniAccusation.udrElements[0].ptEnd = new Point((int)(bmpBoard.Width *.5), (int)(bmpBoard.Height *.5));
udrAniAccusation.udrElements[0].intMaxSteps = 30;
udrAniAccusation.udrElements[0].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[0].ptEnd, udrAniAccusation.udrElements[0].ptStart);
udrAniAccusation.udrElements[0].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[0].ptEnd, udrAniAccusation.udrElements[0].ptStart);
udrAniAccusation.udrElements[0].intStep = 0;
// prison bars (index = 1)
udrAniAccusation.udrElements[1].bmp = new Bitmap(Clue_CS2010.Properties.Resources.prison_bars_large);
udrAniAccusation.udrElements[1].bmp.MakeTransparent(Color.White);
udrAniAccusation.udrElements[1].ptPos =
udrAniAccusation.udrElements[1].ptStart = new Point((int)(bmpBoard.Width *.2), (int)(bmpBoard.Height * .5));
udrAniAccusation.udrElements[1].ptEnd = new Point((int)(bmpBoard.Width * .5), (int)(bmpBoard.Height * .5));
udrAniAccusation.udrElements[1].intMaxSteps = 30;
udrAniAccusation.udrElements[1].dblSizeFactor = 17.5;
udrAniAccusation.udrElements[1].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[1].ptEnd, udrAniAccusation.udrElements[1].ptStart);
udrAniAccusation.udrElements[1].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[1].ptEnd, udrAniAccusation.udrElements[1].ptStart);
udrAniAccusation.udrElements[1].intStep = 0;
udrAniAccusation.bolInit = true;
}
switch (udrAniAccusation.intAnimationStep)
{
case 0:
// move murderer image to center & zoom
// AND move large color bars from ultra-zoom into focus
bool bolQuitUltraZoom = true;
Bitmap bmpTemp = new Bitmap(udrAniAccusation.bmpAccusationBoard);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (int intEleCounter = 0; intEleCounter < udrAniAccusation.udrElements.Length; intEleCounter++)
{
if (udrAniAccusation.udrElements[intEleCounter].intStep < udrAniAccusation.udrElements[intEleCounter].intMaxSteps)
{
udrAniAccusation.udrElements[intEleCounter].intStep++;
udrAniAccusation.udrElements[intEleCounter].ptPos.X = udrAniAccusation.udrElements[intEleCounter].ptStart.X + (int)((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps * udrAniAccusation.udrElements[intEleCounter].dblTravelDistance * Math.Cos(udrAniAccusation.udrElements[intEleCounter].dblTravelAngle));
udrAniAccusation.udrElements[intEleCounter].ptPos.Y = udrAniAccusation.udrElements[intEleCounter].ptStart.Y + (int)((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps * udrAniAccusation.udrElements[intEleCounter].dblTravelDistance * Math.Sin(udrAniAccusation.udrElements[intEleCounter].dblTravelAngle));
bolQuitUltraZoom = false;
}
switch (intEleCounter)
{
case 0:
double dblSFFace_Start = 1.0;
double dblSFFace_End = 2;
udrAniAccusation.udrElements[intEleCounter].dblSizeFactor = dblSFFace_Start + (dblSFFace_End - dblSFFace_Start) * ((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps);
break;
case 1:
// set size factor of bars
double dblSFBars_Start = 17.5;
double dblSFBars_End = 1.0;
udrAniAccusation.udrElements[intEleCounter].dblSizeFactor = dblSFBars_Start + (dblSFBars_End - dblSFBars_Start) * ((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps);
break;
}
Size sz = new Size((int)((double)udrAniAccusation.udrElements[intEleCounter].bmp.Width * udrAniAccusation.udrElements[intEleCounter].dblSizeFactor),
(int)((double)udrAniAccusation.udrElements[intEleCounter].bmp.Height * udrAniAccusation.udrElements[intEleCounter].dblSizeFactor));
Point ptTL = new Point(udrAniAccusation.udrElements[intEleCounter].ptPos.X - sz.Width/2, udrAniAccusation.udrElements[intEleCounter].ptPos.Y - sz.Height / 2);
g.DrawImage(udrAniAccusation.udrElements[intEleCounter].bmp, new Rectangle(ptTL, sz));
}
}
picBoard.Image = bmpTemp; picBoard.Refresh();
if (bolQuitUltraZoom)
{
// join face & bars into one image
// convert image to black & white
// introduce newspaper behind it
// create b/w prison photo (index 0)
Bitmap bmpBarsAndFace_Color = new Bitmap(udrAniAccusation.udrElements[1].bmp.Width, udrAniAccusation.udrElements[1].bmp.Height);
using (Graphics g = Graphics.FromImage(bmpBarsAndFace_Color))
{
g.FillRectangle(new SolidBrush(Color.Brown), new Rectangle(0, 0, bmpBarsAndFace_Color.Width, bmpBarsAndFace_Color.Height));
Size szFace = new Size((int)((double)udrAniAccusation.udrElements[0].bmp.Width * udrAniAccusation.udrElements[0].dblSizeFactor),
(int)((double)udrAniAccusation.udrElements[0].bmp.Height * udrAniAccusation.udrElements[0].dblSizeFactor));
Point ptTLFace = new Point((bmpBarsAndFace_Color.Width - szFace.Width) / 2, (bmpBarsAndFace_Color.Height - szFace.Height) / 2);
g.DrawImage(udrAniAccusation.udrElements[0].bmp, new Rectangle(ptTLFace, szFace));
Size szBars = new Size((int)((double)udrAniAccusation.udrElements[1].bmp.Width * udrAniAccusation.udrElements[1].dblSizeFactor),
(int)((double)udrAniAccusation.udrElements[1].bmp.Height * udrAniAccusation.udrElements[1].dblSizeFactor));
Point ptTLBars = new Point(0, 0);
g.DrawImage(udrAniAccusation.udrElements[1].bmp, new Rectangle(ptTLBars, szBars));
}
udrAniAccusation.udrElements[1].bmp = MakeGrayscale3(bmpBarsAndFace_Color);
// set up newspaper background
udrAniAccusation.udrElements[0].bmp = new Bitmap(Clue_CS2010.Properties.Resources.newsprint);
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[0].bmp))
{
Bitmap bmpText;
Font fnt = new System.Drawing.Font("Franklin Gothic Demi", 12);
Rectangle recDest, recSrc;
Point ptTL = new Point(9, 167);
bmpText = getTextImage(udrMurder.eSuspect.ToString() + " in the " + udrMurder.eRoom.ToString(), fnt);
recDest = new Rectangle(ptTL.X, ptTL.Y, bmpText.Width / 2, bmpText.Height / 2);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage("with the " + udrMurder.eWeapon.ToString(), fnt);
recDest = new Rectangle(ptTL.X, ptTL.Y + 6, bmpText.Width / 2, bmpText.Height / 2);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
}
udrAniAccusation.udrElements[0].ptStart =
udrAniAccusation.udrElements[0].ptPos =
udrAniAccusation.udrElements[0].ptEnd = new Point(bmpBoard.Width / 2, bmpBoard.Height / 2);
udrAniAccusation.udrElements[0].dblSizeFactor = 1.0;
udrAniAccusation.udrElements[0].intStep =
udrAniAccusation.udrElements[0].intMaxSteps = 0;
// set up prison-picture motion
udrAniAccusation.udrElements[1].ptStart = udrAniAccusation.udrElements[1].ptPos;
udrAniAccusation.udrElements[1].ptEnd = new Point(udrAniAccusation.udrElements[0].ptEnd.X - udrAniAccusation.udrElements[0].bmp.Width/2 + 9 +75,
udrAniAccusation.udrElements[0].ptEnd.Y - udrAniAccusation.udrElements[0].bmp.Height/2 + 82 + 40);
udrAniAccusation.udrElements[1].dblSizeFactor = 1.0;
udrAniAccusation.udrElements[1].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[1].ptEnd, udrAniAccusation.udrElements[1].ptStart);
udrAniAccusation.udrElements[1].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[1].ptEnd, udrAniAccusation.udrElements[1].ptStart);
udrAniAccusation.udrElements[1].intStep = 0;
udrAniAccusation.udrElements[1].intMaxSteps = 20;
udrAniAccusation.intAnimationStep++;
}
break;
case 1:
// move b/w face/bars onto newspaper
bool bolQuitPutToPrint = true;
Bitmap bmpTempPutToPrint = new Bitmap(udrAniAccusation.bmpAccusationBoard);
using (Graphics g = Graphics.FromImage(bmpTempPutToPrint))
{
for (int intEleCounter = 0; intEleCounter < udrAniAccusation.udrElements.Length; intEleCounter++)
{
switch (intEleCounter)
{
case 0:
g.DrawImage(udrAniAccusation.udrElements[intEleCounter].bmp, udrAniAccusation.udrElements[intEleCounter].ptPos.X - udrAniAccusation.udrElements[intEleCounter].bmp.Width / 2, udrAniAccusation.udrElements[intEleCounter].ptPos.Y - udrAniAccusation.udrElements[intEleCounter].bmp.Height / 2);
break;
case 1:
if (udrAniAccusation.udrElements[intEleCounter].intStep < udrAniAccusation.udrElements[1].intMaxSteps)
{
udrAniAccusation.udrElements[intEleCounter].intStep++;
udrAniAccusation.udrElements[intEleCounter].ptPos.X = udrAniAccusation.udrElements[intEleCounter].ptStart.X + (int)((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps * udrAniAccusation.udrElements[intEleCounter].dblTravelDistance * Math.Cos(udrAniAccusation.udrElements[intEleCounter].dblTravelAngle));
udrAniAccusation.udrElements[intEleCounter].ptPos.Y = udrAniAccusation.udrElements[intEleCounter].ptStart.Y + (int)((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps * udrAniAccusation.udrElements[intEleCounter].dblTravelDistance * Math.Sin(udrAniAccusation.udrElements[intEleCounter].dblTravelAngle));
bolQuitPutToPrint = false;
}
double dblSFFaceAndBars_Start = 1.0;
double dblSFFaceAndBars_End = 150.0 / (double)udrAniAccusation.udrElements[intEleCounter].bmp.Width;
/// = F + (F' - F)(n/N)
udrAniAccusation.udrElements[intEleCounter].dblSizeFactor = dblSFFaceAndBars_Start + (dblSFFaceAndBars_End - dblSFFaceAndBars_Start) * ((double)udrAniAccusation.udrElements[intEleCounter].intStep / (double)udrAniAccusation.udrElements[intEleCounter].intMaxSteps);
Size sz = new Size((int)((double)udrAniAccusation.udrElements[intEleCounter].bmp.Width * udrAniAccusation.udrElements[intEleCounter].dblSizeFactor),
(int)((double)udrAniAccusation.udrElements[intEleCounter].bmp.Height * udrAniAccusation.udrElements[intEleCounter].dblSizeFactor));
Point ptTL = new Point(udrAniAccusation.udrElements[intEleCounter].ptPos.X - sz.Width / 2, udrAniAccusation.udrElements[intEleCounter].ptPos.Y - sz.Height / 2);
g.DrawImage(udrAniAccusation.udrElements[intEleCounter].bmp, new Rectangle(ptTL, sz));
break;
}
}
}
picBoard.Image = bmpTempPutToPrint; picBoard.Refresh();
if (bolQuitPutToPrint)
{
// create four base rotated images during pause
Bitmap bmpNewsPaper = new Bitmap(udrAniAccusation.udrElements[0].bmp.Width, udrAniAccusation.udrElements[0].bmp.Height);
using (Graphics g = Graphics.FromImage(bmpNewsPaper))
{
g.DrawImage(udrAniAccusation.udrElements[0].bmp, 0, 0);
double dblSFFaceAndBars_Start = 1.0;
double dblSFFaceAndBars_End = 150.0 / (double)udrAniAccusation.udrElements[1].bmp.Width;
/// = F + (F' - F)(n/N)
udrAniAccusation.udrElements[1].dblSizeFactor = dblSFFaceAndBars_Start + (dblSFFaceAndBars_End - dblSFFaceAndBars_Start) * ((double)udrAniAccusation.udrElements[1].intStep / (double)udrAniAccusation.udrElements[1].intMaxSteps);
Size sz = new Size((int)((double)udrAniAccusation.udrElements[1].bmp.Width * udrAniAccusation.udrElements[1].dblSizeFactor),
(int)((double)udrAniAccusation.udrElements[1].bmp.Height * udrAniAccusation.udrElements[1].dblSizeFactor));
Point ptTL = new Point(9, 82);
g.DrawImage(udrAniAccusation.udrElements[1].bmp, new Rectangle(ptTL, sz));
}
udrAniAccusation.udrNewspaper.cBmp = new classRotatedImage();
double dblAspectRatioXOverY = (double)bmpNewsPaper.Width / (double)bmpNewsPaper.Height;
udrAniAccusation.udrNewspaper.dblSizeFactor = 2.0;
double dblReducedSizeFactor = 1.0 / udrAniAccusation.udrNewspaper.dblSizeFactor;
int intNewWidth = (int)((double)bmpNewsPaper.Width * dblReducedSizeFactor);
int intNewHeight = (int)((double)intNewWidth / dblAspectRatioXOverY);
udrAniAccusation.udrNewspaper.cBmp.createBaseImage(new Bitmap( bmpNewsPaper, intNewWidth, intNewHeight));
udrAniAccusation.udrNewspaper.cBmp.getImage(1);
udrAniAccusation.udrNewspaper.cBmp.getImage(2);
udrAniAccusation.udrNewspaper.cBmp.getImage(3);
udrAniAccusation.udrNewspaper.ptPos = new Point(bmpBoard.Width / 2, bmpBoard.Height / 2);
udrAniAccusation.intAnimationStep++;
}
break;
default:
// zoom out newspaper in quick rotation
udrAniAccusation.intAnimationStep++;
Bitmap bmpTempSpinningNewspaper = new Bitmap(udrAniAccusation.bmpAccusationBoard);
using (Graphics g = Graphics.FromImage(bmpTempSpinningNewspaper))
{
udrAniAccusation.udrNewspaper.dblSizeFactor *= 1.1;
udrAniAccusation.udrNewspaper.intImage = (udrAniAccusation.udrNewspaper.intImage + 1) % 16;
Bitmap bmpCurrentNewspaper = udrAniAccusation.udrNewspaper.cBmp.getImage(udrAniAccusation.udrNewspaper.intImage);
Size szCurrentNewspaper = new Size((int)(bmpCurrentNewspaper.Width * udrAniAccusation.udrNewspaper.dblSizeFactor),
(int)(bmpCurrentNewspaper.Height * udrAniAccusation.udrNewspaper.dblSizeFactor));
Point ptTLCurrentNewspaper = new Point(udrAniAccusation.udrNewspaper.ptPos.X - szCurrentNewspaper.Width / 2,
udrAniAccusation.udrNewspaper.ptPos.Y - szCurrentNewspaper.Height / 2);
g.DrawImage(bmpCurrentNewspaper, new Rectangle(ptTLCurrentNewspaper, szCurrentNewspaper));
}
picBoard.Image = bmpTempSpinningNewspaper;picBoard.Refresh();
if (udrAniAccusation.udrNewspaper.dblSizeFactor > 15)
{
GameOver();
return;
}
break;
}
setDelayTimer(10);
}
void AnimateAccusation_WithdrawAccusingSuspect()
{
if (!udrAniAccusation.bolInit)
{
udrAniAccusation.bolInit = true;
udrAniAccusation.udrElements = new udtAnimationInfo[1];
Point ptSuspectTL = new Point(15, 420);
udrAniAccusation.udrElements[0].dblSizeFactor = 1.3;
udrAniAccusation.udrElements[0].bmp = new Bitmap(bmpSuspects[intSuspectTurn]);
udrAniAccusation.udrElements[0].ptPos = //Point ptSuspectTL = new Point(15, 420);
udrAniAccusation.udrElements[0].ptStart = new Point(15 + udrAniAccusation.udrElements[0].bmp.Width / 2, 420 + udrAniAccusation.udrElements[0].bmp.Height / 2);
udrAniAccusation.udrElements[0].ptEnd = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[0].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[0].ptEnd, udrAniAccusation.udrElements[0].ptStart);
udrAniAccusation.udrElements[0].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[0].ptEnd, udrAniAccusation.udrElements[0].ptStart);
udrAniAccusation.udrElements[0].intMaxSteps = 20;
udrAniAccusation.udrElements[0].intStep = 0;
udrAniAccusation.intAnimationStep = 0;
}
switch (udrAniAccusation.intAnimationStep)
{
case 0: // move suspect head to center of screen
if (udrAniAccusation.udrElements[0].intStep < udrAniAccusation.udrElements[0].intMaxSteps)
{
Bitmap bmpTemp = new Bitmap(bmpGameBoard);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
udrAniAccusation.udrElements[0].intStep++;
double dblPercentageDistanceTravelled = (double)udrAniAccusation.udrElements[0].intStep / (double)udrAniAccusation.udrElements[0].intMaxSteps;
udrAniAccusation.udrElements[0].ptPos.X = udrAniAccusation.udrElements[0].ptStart.X + (int)(udrAniAccusation.udrElements[0].dblTravelDistance * dblPercentageDistanceTravelled * Math.Cos(udrAniAccusation.udrElements[0].dblTravelAngle));
udrAniAccusation.udrElements[0].ptPos.Y = udrAniAccusation.udrElements[0].ptStart.Y + (int)(udrAniAccusation.udrElements[0].dblTravelDistance * dblPercentageDistanceTravelled * Math.Sin(udrAniAccusation.udrElements[0].dblTravelAngle));
int intImageSize = (int)(udrAniAccusation.udrElements[0].bmp.Width * udrAniAccusation.udrElements[0].dblSizeFactor);
Rectangle recDest = new Rectangle(udrAniAccusation.udrElements[0].ptPos.X - intImageSize / 2, udrAniAccusation.udrElements[0].ptPos.Y - intImageSize / 2, intImageSize, intImageSize);
Rectangle recSrc = new Rectangle(0, 0, udrAniAccusation.udrElements[0].bmp.Width, udrAniAccusation.udrElements[0].bmp.Height);
g.DrawImage(udrAniAccusation.udrElements[0].bmp, recDest, recSrc, GraphicsUnit.Pixel);
udrAniAccusation.udrElements[0].dblSizeFactor *= 1.05;
}
picBoard.Image = bmpTemp; picBoard.Refresh();
}
else
{
udrAniAccusation.intAnimationStep++;
udrAniAccusation.bmpAccusationForeground = new Bitmap(bmpBoard.Width, bmpBoard.Height);
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpAccusationForeground))
{
Rectangle recDest, recSrc;
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, udrAniAccusation.bmpAccusationForeground.Width, udrAniAccusation.bmpAccusationForeground.Height));
Bitmap bmpBubble = new Bitmap(Clue_CS2010.Properties.Resources.SuggestionBubble, 300, 500);
bmpBubble.MakeTransparent(Color.White);
bmpBubble.RotateFlip(RotateFlipType.Rotate270FlipY);
bmpBubble.MakeTransparent(Color.White);
Point ptTL = new Point((udrAniAccusation.bmpAccusationForeground.Width - bmpBubble.Width) / 2, udrAniAccusation.bmpAccusationForeground.Height - bmpBubble.Height);
recDest = new Rectangle(ptTL, bmpBubble.Size);
recSrc = new Rectangle(1, 1, bmpBubble.Width - 2, bmpBubble.Height - 2);
g.DrawImage(bmpBubble, recDest, recSrc, GraphicsUnit.Pixel);
Bitmap bmpText;
Font fnt = new System.Drawing.Font("blackadder itc", 36);
int intTop = 50;
int intVLineSpacine = 50;
int intLeftText = 5;
bmpText = getTextImage("Forgive my indiscretion", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage("I shall remove ", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop + 2 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(" myself from the game.", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop + 3 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
}
udrAniAccusation.udrElements[0].intStep = 0;
udrAniAccusation.udrElements[0].intMaxSteps = 80;
udrAniAccusation.bmpAccusationForeground.MakeTransparent(Color.White);
}
break;
case 1: // write report that accusing suspect has been eliminated & shrink accusing suspect's image
Bitmap bmpTemp_WriteReport = new Bitmap(bmpGameBoard);
using (Graphics g = Graphics.FromImage(bmpTemp_WriteReport))
{
udrAniAccusation.udrElements[0].intStep++;
udrAniAccusation.udrElements[0].dblSizeFactor *= .95;
int intImageSize = (int)(udrAniAccusation.udrElements[0].bmp.Width * udrAniAccusation.udrElements[0].dblSizeFactor);
if (intImageSize < 1)
intImageSize = 1;
Rectangle recDest = new Rectangle(udrAniAccusation.udrElements[0].ptPos.X - intImageSize / 2, udrAniAccusation.udrElements[0].ptPos.Y - intImageSize / 2, intImageSize, intImageSize);
Rectangle recSrc = new Rectangle(0, 0, udrAniAccusation.udrElements[0].bmp.Width, udrAniAccusation.udrElements[0].bmp.Height);
g.DrawImage(udrAniAccusation.udrElements[0].bmp, recDest, recSrc, GraphicsUnit.Pixel);
g.DrawImage(udrAniAccusation.bmpAccusationForeground, new Point(0, 0));
}
picBoard.Image = bmpTemp_WriteReport;
if (udrAniAccusation.udrElements[0].intStep > udrAniAccusation.udrElements[0].intMaxSteps)
{
udrAniAccusation.intAnimationStep++;
}
break;
case 2: // quit
cSuspects[intSuspectTurn].bolEliminated = true;
cSuspects[intSuspectTurn].removeSuspectFromDoorways();
eMode = enuMode.endTurn;
break;
}
setDelayTimer(10);
}
void AnimateAccusation_RetractCards()
{
int intSizeFloodlights = 200;
int intMaxSteps = 15;
if (!udrAniAccusation.bolInit)
{
/// room
udrAniAccusation.udrElements[(int)enuCardType.room].bmp = cCards[(int)classCard.getECardFromERoom(udrMurder.eRoom)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.room].ptStart = udrAniAccusation.udrElements[(int)enuCardType.room].ptPos;
udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[(int)enuCardType.room].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.room].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.room].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.room].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity = udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelDistance / udrAniAccusation.udrElements[(int)enuCardType.room].intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.room].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.room].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle));
/// weapon
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp = cCards[(int)classCard.getECardFromEWeapon(udrMurder.eWeapon)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart = udrAniAccusation.udrElements[(int)enuCardType.weapon].ptPos;
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[(int)enuCardType.weapon].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.weapon].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity = udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelDistance / udrAniAccusation.udrElements[(int)enuCardType.weapon].intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.weapon].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.weapon].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle));
/// Suspect
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp = cCards[(int)classCard.getECardFromESuspect(udrMurder.eSuspect)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart = udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptPos;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity = udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelDistance / udrAniAccusation.udrElements[(int)enuCardType.Suspect].intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle));
udrAniAccusation.intAnimationStep = 0;
udrAniAccusation.bolInit = true;
}
Bitmap bmpCard = cCardUnknown.cBmp.getImage(0);
Bitmap bmpShadeCard = MakeGrayscale3(new Bitmap(cCardUnknown.cBmp.getImage(0)));
Bitmap bmpTempShade = new Bitmap(udrAniAccusation.bmpShadedAccusationBoard);
Bitmap bmpTemp = new Bitmap(udrAniAccusation.bmpAccusationBoard);
bool bolQuit = true;
using (Graphics gGray = Graphics.FromImage(bmpTempShade)) // draw everything in gray-scale
{
using (Graphics gForeground = Graphics.FromImage(bmpTemp)) // used to draw the animated cards in color onto a foreground image of 3 elements (3 ele + 3 cards in color)
{
gForeground.DrawImage(udrAniAccusation.bmpAccusationForeground, new Point(0, 0));
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
{
udrAniAccusation.udrElements[(int)eTypeCounter].intStep++;
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep >= udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps)
{
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos = udrAniAccusation.udrElements[(int)eTypeCounter].ptEnd;
}
else
{
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X += udrAniAccusation.udrElements[(int)eTypeCounter].velTravel.X;
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y += udrAniAccusation.udrElements[(int)eTypeCounter].velTravel.Y;
bolQuit = false;
}
gGray.DrawImage(bmpShadeCard, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
gForeground.DrawImage(bmpCard, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
}
gGray.DrawImage(udrAniAccusation.bmpAccusationForegroundGray, new Point(0, 0));
}
/// we now have
/// - a gray scale foreground drawn onto the gray-scale background (3 gray cards + 3 gray elements)
/// - a color foreground w/ 3 elements + 3 cards
/// we need to generate a mask for the floodlights
Point ptFinalFloodLightPos = getRoomCenter(enuRooms._numRooms);
Bitmap bmpFloodLights_copy = new Bitmap(bmpFloodlights);
using (Graphics g = Graphics.FromImage(bmpFloodLights_copy))
{
bool bolMoveToEnd = (udrAniAccusation.intAnimationStep > intMaxSteps * 4);
for (int intFloodlightCounter = 0; intFloodlightCounter < udrAniAccusation.udrFloodlights.Length; intFloodlightCounter++)
{
g.FillEllipse(br, new Rectangle(udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.X - intSizeFloodlights, udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.Y - intSizeFloodlights, 2 * intSizeFloodlights, 2 * intSizeFloodlights));
}
}
endFloodLight:
bmpFloodLights_copy.MakeTransparent(clrFloordlights);
// now we also have a blue image with three red circles
// make red circles transparent
// superimpose this blue mask on top of colored foreground
Bitmap bmpMaskedColouredForeground = new Bitmap(bmpTemp);
using (Graphics g = Graphics.FromImage(bmpMaskedColouredForeground))
g.DrawImage(bmpFloodLights_copy, new Point(0, 0));
// make blue transparent (keep colored image only where the transparent red-circles were)
bmpMaskedColouredForeground.MakeTransparent(clrField);
// copy these colored circles on top of final output image
gGray.DrawImage(bmpMaskedColouredForeground, new Point(0, 0));
}
picBoard.Image = bmpTempShade;
udrAniAccusation.intAnimationStep++;
if (bolQuit)
{
eAccusationMode = enuAccuseAnimationMode.withdrawAccusingSuspect;
}
setDelayTimer(10);
}
void AnimateAccusation_HideCards()
{
int intSizeFloodlights = 200;
if (!udrAniAccusation.bolInit)
{
for (int intCardCounter = 0; intCardCounter < udrAniAccusation.udrElements.Length; intCardCounter++)
udrAniAccusation.udrElements[intCardCounter].intStep = 0;
udrAniAccusation.bolInit = true;
}
Bitmap bmpCard = cCardUnknown.cBmp.getImage(0);
Bitmap bmpTemp = new Bitmap(udrAniAccusation.bmpAccusationBoard);
bool bolQuit = true;
using (Graphics gForeground = Graphics.FromImage(bmpTemp)) // used to draw the animated cards in color onto a foreground image of 3 elements (3 ele + 3 cards in color)
{
gForeground.DrawImage(udrAniAccusation.bmpAccusationForeground, new Point(0, 0));
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
{
udrAniAccusation.udrElements[(int)eTypeCounter].intStep++;
int intMidway = udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps / 2;
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep > intMidway)
{
int intStepsPastMid = udrAniAccusation.udrElements[(int)eTypeCounter].intStep - intMidway;
double dblPercentageLeft = ((double)intStepsPastMid / (double)intMidway);
int intWidth = (int)(dblPercentageLeft * (double)udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width);
if (intWidth < 1)
intWidth = 1;
Bitmap bmpFacedown = new Bitmap(cCardUnknown.cBmp.getImage(0), intWidth, udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height);
gForeground.DrawImage(bmpFacedown, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - bmpFacedown.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - bmpFacedown.Height / 2);
}
else
{
double dblPercentageLeft = ((double)(intMidway - udrAniAccusation.udrElements[(int)eTypeCounter].intStep) / (double)intMidway);
int intWidth = (int)(dblPercentageLeft * (double)cCardUnknown.cBmp.getImage(0).Width);
if (intWidth < 1)
intWidth = 1;
Bitmap bmpFaceup = new Bitmap(udrAniAccusation.udrElements[(int)eTypeCounter].bmp, intWidth, udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height);
gForeground.DrawImage(bmpFaceup, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - bmpFaceup.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - bmpFaceup.Height / 2);
}
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep < udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps)
bolQuit = false;
}
}
/// we now have
/// - a gray scale foreground drawn onto the gray-scale background ( 3 gray elements)
/// - a color foreground w/ 3 elements + 3 cards
/// we need to generate a mask for the floodlights
Point ptFinalFloodLightPos = getRoomCenter(enuRooms._numRooms);
Bitmap bmpFloodLights_copy = new Bitmap(bmpFloodlights);
using (Graphics g = Graphics.FromImage(bmpFloodLights_copy))
g.FillEllipse(br, new Rectangle(udrAniAccusation.udrFloodlights[0].ptPos.X - intSizeFloodlights, udrAniAccusation.udrFloodlights[0].ptPos.Y - intSizeFloodlights, 2 * intSizeFloodlights, 2 * intSizeFloodlights));
bmpFloodLights_copy.MakeTransparent(clrFloordlights);
// now we also have a blue image with three red circles
// make red circles transparent
// superimpose this blue mask on top of colored foreground
Bitmap bmpMaskedColouredForeground = new Bitmap(bmpTemp);
using (Graphics g = Graphics.FromImage(bmpMaskedColouredForeground))
g.DrawImage(bmpFloodLights_copy, new Point(0, 0));
// make blue transparent (keep colored image only where the transparent red-circles were)
bmpMaskedColouredForeground.MakeTransparent(clrField);
// copy the circle of colored image (flood light) on top of final output image
Bitmap bmpTempShade = new Bitmap(udrAniAccusation.bmpShadedAccusationBoard);
using (Graphics gGray = Graphics.FromImage(bmpTempShade)) // draw everything in gray-scale
gGray.DrawImage(bmpMaskedColouredForeground, new Point(0, 0));
picBoard.Image = bmpTempShade; picBoard.Refresh();
udrAniAccusation.intAnimationStep++;
if (bolQuit)
{
eAccusationMode = enuAccuseAnimationMode.retractCards;
}
setDelayTimer(10);
}
void AnimateAccusation_ShowCards()
{
int intSizeFloodlights = 200;
int intMaxSteps = 30;
if (!udrAniAccusation.bolInit)
{
udrAniAccusation.bolInit = true;
/// room
udrAniAccusation.udrElements[(int)enuCardType.room].bmp = cCards[(int)classCard.getECardFromERoom(udrMurder.eRoom)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.room].ptStart =
udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd =
udrAniAccusation.udrElements[(int)enuCardType.room].ptPos;
udrAniAccusation.udrElements[(int)enuCardType.room].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.room].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAcceleration =
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle =
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelDistance =
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.room].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle));
/// Suspect
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp = cCards[(int)classCard.getECardFromESuspect(udrMurder.eSuspect)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptPos;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAcceleration =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelDistance =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle));
/// weapon
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp = cCards[(int)classCard.getECardFromEWeapon(udrMurder.eWeapon)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart =
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd =
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptPos;
udrAniAccusation.udrElements[(int)enuCardType.weapon].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.weapon].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAcceleration =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelDistance =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.weapon].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle));
udrAniAccusation.intAnimationStep = 0;
udrAniAccusation.bolInit = true;
// prepare shaded accusation board
udrAniAccusation.bmpShadedAccusationBoard = MakeGrayscale3(bmpGameBoard);
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpShadedAccusationBoard))
{
g.DrawImage(udrAniAccusation.bmpAccusationForegroundGray, new Point(0, 0));
// draw center rectangle w/o cards
Rectangle recDest = new Rectangle(279, 231, 418 - 279, 426 - 231);
g.FillRectangle(new SolidBrush(bmpBoard.GetPixel(bmpBoard.Width / 2, bmpBoard.Height / 2)), recDest);
Bitmap bmpAccusingSuspectAndBubble = getAccusingSuspectAndBubbleImage((enuSuspects)intSuspectTurn, udrAniAccusation.udrAccusation);
bmpAccusingSuspectAndBubble.MakeTransparent(Color.White);
g.DrawImage(bmpAccusingSuspectAndBubble, new Point(0, 0));
}
// prepare accusation board
udrAniAccusation.bmpAccusationBoard = new Bitmap (bmpGameBoard);
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpAccusationBoard))
{
g.DrawImage(udrAniAccusation.bmpAccusationForeground, new Point(0, 0));
// draw center rectangle w/o cards
Rectangle recDest = new Rectangle(279, 231, 418 - 279, 426 - 231);
g.FillRectangle(new SolidBrush(bmpBoard.GetPixel(bmpBoard.Width / 2, bmpBoard.Height / 2)), recDest);
Bitmap bmpAccusingSuspectAndBubble = getAccusingSuspectAndBubbleImage((enuSuspects)intSuspectTurn, udrAniAccusation.udrAccusation);
bmpAccusingSuspectAndBubble.MakeTransparent(Color.White);
g.DrawImage(bmpAccusingSuspectAndBubble, new Point(0, 0));
}
}
Bitmap bmpCard = cCardUnknown.cBmp.getImage(0);
Bitmap bmpTemp = new Bitmap(udrAniAccusation.bmpAccusationBoard);
bool bolQuit = true;
using (Graphics gForeground = Graphics.FromImage(bmpTemp)) // used to draw the animated cards in color onto a foreground image of 3 elements (3 ele + 3 cards in color)
{
gForeground.DrawImage(udrAniAccusation.bmpAccusationForeground, new Point(0, 0));
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
{
udrAniAccusation.udrElements[(int)eTypeCounter].intStep++;
int intMidway = udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps / 2;
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep > intMidway)
{
int intStepsPastMid = udrAniAccusation.udrElements[(int)eTypeCounter].intStep - intMidway;
double dblPercentageLeft = ((double)intStepsPastMid / (double)intMidway);
int intWidth = (int)(dblPercentageLeft * (double)udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width);
if (intWidth<1)
intWidth = 1;
Bitmap bmpFaceup = new Bitmap(udrAniAccusation.udrElements[(int)eTypeCounter].bmp, intWidth, udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height);
gForeground.DrawImage(bmpFaceup, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - bmpFaceup.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - bmpFaceup.Height / 2);
}
else
{
double dblPercentageLeft = ((double)(intMidway - udrAniAccusation.udrElements[(int)eTypeCounter].intStep) / (double)intMidway);
int intWidth = (int)(dblPercentageLeft * (double)cCardUnknown.cBmp.getImage(0).Width);
if (intWidth < 1)
intWidth = 1;
Bitmap bmpFacedown = new Bitmap(cCardUnknown.cBmp.getImage(0), intWidth, udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height);
gForeground.DrawImage(bmpFacedown, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - bmpFacedown.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - bmpFacedown.Height / 2);
}
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep < udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps)
bolQuit = false;
}
}
/// we now have
/// - a gray scale foreground drawn onto the gray-scale background ( 3 gray elements)
/// - a color foreground w/ 3 elements + 3 cards
/// we need to generate a mask for the floodlights
Point ptFinalFloodLightPos = getRoomCenter(enuRooms._numRooms);
Bitmap bmpFloodLights_copy = new Bitmap(bmpFloodlights);
using (Graphics g = Graphics.FromImage(bmpFloodLights_copy))
g.FillEllipse(br, new Rectangle(udrAniAccusation.udrFloodlights[0].ptPos.X - intSizeFloodlights, udrAniAccusation.udrFloodlights[0].ptPos.Y - intSizeFloodlights, 2 * intSizeFloodlights, 2 * intSizeFloodlights));
bmpFloodLights_copy.MakeTransparent(clrFloordlights);
// now we also have a blue image with three red circles
// make red circles transparent
// superimpose this blue mask on top of colored foreground
Bitmap bmpMaskedColouredForeground = new Bitmap(bmpTemp);
using (Graphics g = Graphics.FromImage(bmpMaskedColouredForeground))
g.DrawImage(bmpFloodLights_copy, new Point(0, 0));
// make blue transparent (keep colored image only where the transparent red-circles were)
bmpMaskedColouredForeground.MakeTransparent(clrField);
// copy the circle of colored image (flood light) on top of final output image
Bitmap bmpTempShade = new Bitmap(udrAniAccusation.bmpShadedAccusationBoard);
using (Graphics gGray = Graphics.FromImage(bmpTempShade)) // draw everything in gray-scale
gGray.DrawImage(bmpMaskedColouredForeground, new Point(0, 0));
picBoard.Image = bmpTempShade; picBoard.Refresh();
udrAniAccusation.intAnimationStep++;
if (bolQuit)
{
if (compareTwoMurderScenes(udrAniAccusation.udrAccusation, udrMurder))
{ // accusation is correct
eAccusationMode = enuAccuseAnimationMode.showNewspaper;
udrAniAccusation.bmpAccusationBoard = new Bitmap(picBoard.Image);
}
else
{ // accusation is false
eAccusationMode = enuAccuseAnimationMode.hideCards;
}
}
setDelayTimer(10);
}
bool compareTwoMurderScenes(udtMurder udrMurderA, udtMurder udrMurderB)
{
return (udrMurderA.eSuspect == udrMurderB.eSuspect
&& udrMurderA.eRoom == udrMurderB.eRoom
&& udrMurderA.eWeapon == udrMurderB.eWeapon);
}
void AnimateAccusation_PrepareToShowCards()
{
int intSizeFloodlights = 200;
int intMaxSteps = 15;
if (!udrAniAccusation.bolInit)
{
/// room
udrAniAccusation.udrElements[(int)enuCardType.room].bmp = cCards[(int)classCard.getECardFromERoom(udrMurder.eRoom)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.room].ptPos =
udrAniAccusation.udrElements[(int)enuCardType.room].ptStart = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd = new Point(udrAniAccusation.udrElements[(int)enuCardType.room].ptStart.X - udrAniAccusation.udrElements[(int)enuCardType.room].bmp.Width, getRoomCenter(enuRooms._numRooms).Y);
udrAniAccusation.udrElements[(int)enuCardType.room].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.room].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.room].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.room].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity = udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelDistance / udrAniAccusation.udrElements[(int)enuCardType.room].intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.room].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.room].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle));
/// weapon
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp = cCards[(int)classCard.getECardFromEWeapon(udrMurder.eWeapon)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptPos =
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd = new Point(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart.X + udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp.Width, getRoomCenter(enuRooms._numRooms).Y);
udrAniAccusation.udrElements[(int)enuCardType.weapon].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.weapon].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity = udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelDistance / udrAniAccusation.udrElements[(int)enuCardType.weapon].intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.weapon].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.weapon].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle));
/// Suspect
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp = cCards[(int)classCard.getECardFromESuspect(udrMurder.eSuspect)].cBmp.getImage(0);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptPos =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart = getRoomCenter(enuRooms._numRooms);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd = new Point(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart.X, getRoomCenter(enuRooms._numRooms).Y);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intStep = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurning =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleFacing =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity = udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelDistance / udrAniAccusation.udrElements[(int)enuCardType.Suspect].intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].velTravel.X = (int)(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].velTravel.Y = (int)(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle));
udrAniAccusation.udrFloodlights = new udtAnimationInfo[1];
for (int intFloodlightCounter = 0; intFloodlightCounter < udrAniAccusation.udrFloodlights.Length; intFloodlightCounter++)
{
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptStart
= new Point(((int)rnd.NextDouble() * 1000) % 2 == 0 ? bmpBoard.Width + 50 : -50,
(int)rnd.NextDouble() * bmpBoard.Height);
udrAniAccusation.udrFloodlights[intFloodlightCounter].intMaxSteps =
udrAniAccusation.udrFloodlights[intFloodlightCounter].intStep = 0;
}
udrAniAccusation.intAnimationStep = 0;
udrAniAccusation.bolInit = true;
}
Bitmap bmpCard = cCardUnknown.cBmp.getImage(0);
Bitmap bmpShadeCard = MakeGrayscale3(new Bitmap(cCardUnknown.cBmp.getImage(0)));
Bitmap bmpTempShade = new Bitmap(udrAniAccusation.bmpShadedAccusationBoard);
Bitmap bmpTemp = new Bitmap(udrAniAccusation.bmpAccusationBoard);
bool bolQuit = false;
using (Graphics gGray = Graphics.FromImage(bmpTempShade)) // draw everything in gray-scale
{
using (Graphics gForeground = Graphics.FromImage(bmpTemp)) // used to draw the animated cards in color onto a foreground image of 3 elements (3 ele + 3 cards in color)
{
gForeground.DrawImage(udrAniAccusation.bmpAccusationForeground, new Point(0, 0));
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
{
if (udrAniAccusation.intAnimationStep > 20)
{
udrAniAccusation.udrElements[(int)eTypeCounter].intStep++;
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep >= udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps)
{
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos = udrAniAccusation.udrElements[(int)eTypeCounter].ptEnd;
}
else
{
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X += udrAniAccusation.udrElements[(int)eTypeCounter].velTravel.X;
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y += udrAniAccusation.udrElements[(int)eTypeCounter].velTravel.Y;
}
}
gGray.DrawImage(bmpShadeCard, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
gForeground.DrawImage(bmpCard, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
}
gGray.DrawImage(udrAniAccusation.bmpAccusationForegroundGray, new Point(0, 0));
}
/// we now have
/// - a gray scale foreground drawn onto the gray-scale background (3 gray cards + 3 gray elements)
/// - a color foreground w/ 3 elements + 3 cards
/// we need to generate a mask for the floodlights
Point ptFinalFloodLightPos = getRoomCenter(enuRooms._numRooms);
Bitmap bmpFloodLights_copy = new Bitmap(bmpFloodlights);
using (Graphics g = Graphics.FromImage(bmpFloodLights_copy))
{
bool bolMoveToEnd = (udrAniAccusation.intAnimationStep > intMaxSteps* 4);
for (int intFloodlightCounter = 0; intFloodlightCounter < udrAniAccusation.udrFloodlights.Length; intFloodlightCounter++)
{
if (udrAniAccusation.udrFloodlights[intFloodlightCounter].intStep >= udrAniAccusation.udrFloodlights[intFloodlightCounter].intMaxSteps)
{
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelDistance = 0;
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos = udrAniAccusation.udrFloodlights[intFloodlightCounter].ptEnd;
if ((bolMoveToEnd && udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos == ptFinalFloodLightPos))
{
g.FillEllipse(br, new Rectangle(udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.X - intSizeFloodlights, udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.Y - intSizeFloodlights, 2 * intSizeFloodlights, 2 * intSizeFloodlights));
bolQuit = true;
goto endFloodLight;
}
bool bolLoop = true;
while (udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelDistance < 200 && bolLoop)
{
udrAniAccusation.udrFloodlights[intFloodlightCounter].intStep = 0;
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptStart = udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos;
if (bolMoveToEnd)
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptEnd = ptFinalFloodLightPos;
else
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptEnd = new Point((int)(rnd.NextDouble() * 10000) % (int)(bmpBoard.Width*2.0/3.0) + (int)(bmpBaize.Width * 1.0/6.0), (int)(rnd.NextDouble() * 10000) % (int)(bmpBoard.Height * .4) + (int)(bmpBoard.Height * .1));
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblAngleFacing =
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblAngleTurning =
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrFloodlights[intFloodlightCounter].ptEnd, udrAniAccusation.udrFloodlights[intFloodlightCounter].ptStart);
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrFloodlights[intFloodlightCounter].ptEnd, udrAniAccusation.udrFloodlights[intFloodlightCounter].ptStart);
int intStepSize = 20;
if (udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelDistance < intStepSize)
{
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos = udrAniAccusation.udrFloodlights[intFloodlightCounter].ptEnd;
bolLoop = false;
}
else
{
udrAniAccusation.udrFloodlights[intFloodlightCounter].intMaxSteps = (int)(udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelDistance / 20);
udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelInitialVelocity = udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelDistance / udrAniAccusation.udrFloodlights[intFloodlightCounter].intMaxSteps;
udrAniAccusation.udrFloodlights[intFloodlightCounter].velTravel.X = (int)(udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelInitialVelocity * Math.Cos(udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelAngle));
udrAniAccusation.udrFloodlights[intFloodlightCounter].velTravel.Y = (int)(udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelInitialVelocity * Math.Sin(udrAniAccusation.udrFloodlights[intFloodlightCounter].dblTravelAngle));
bolLoop = false;
}
}
}
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.X += udrAniAccusation.udrFloodlights[intFloodlightCounter].velTravel.X;
udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.Y += udrAniAccusation.udrFloodlights[intFloodlightCounter].velTravel.Y;
udrAniAccusation.udrFloodlights[intFloodlightCounter].intStep++;
g.FillEllipse(br, new Rectangle(udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.X - intSizeFloodlights, udrAniAccusation.udrFloodlights[intFloodlightCounter].ptPos.Y - intSizeFloodlights, 2 * intSizeFloodlights, 2 * intSizeFloodlights));
}
}
endFloodLight:
bmpFloodLights_copy.MakeTransparent(clrFloordlights);
// now we also have a blue image with three red circles
// make red circles transparent
// superimpose this blue mask on top of colored foreground
Bitmap bmpMaskedColouredForeground = new Bitmap(bmpTemp);
using (Graphics g = Graphics.FromImage(bmpMaskedColouredForeground))
g.DrawImage(bmpFloodLights_copy, new Point (0,0));
// make blue transparent (keep colored image only where the transparent red-circles were)
bmpMaskedColouredForeground.MakeTransparent(clrField);
// copy these colored circles on top of final output image
gGray.DrawImage(bmpMaskedColouredForeground, new Point(0, 0));
}
picBoard.Image = bmpTempShade;
udrAniAccusation.intAnimationStep++;
if (bolQuit)
{
if (cSuspects[intSuspectTurn].bolPlayerControlled
|| compareTwoMurderScenes(udrAniAccusation.udrAccusation, udrMurder))
{
eAccusationMode = enuAccuseAnimationMode.showCards;
}
else
{
eAccusationMode = enuAccuseAnimationMode.withdrawAccusingSuspect;
}
}
setDelayTimer(10);
}
/// <summary>
/// copied from http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale
/// </summary>
/// <param name="original"></param>
/// <returns></returns>
public Bitmap MakeGrayscale3(Bitmap original)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
//get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
//create the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(new float[][] {
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
}
);
//create some image attributes
ImageAttributes attributes = new ImageAttributes();
//set the color matrix attribute
attributes.SetColorMatrix(colorMatrix);
//draw the original image on the new image
//using the grayscale color matrix
g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
//dispose the Graphics object
g.Dispose();
return newBitmap;
}
void AnimateAccusation_drawAccusation()
{
if (!udrAniAccusation.bolInit)
{
udrAniAccusation.bolInit = true;
btnAccuse_Ok.Visible = false;
cLibPicTrayRooms.Visible =
cLibPicTrayRooms.tmrRotate.Enabled = false;
cLibPicTrayWeapons.Visible =
cLibPicTrayWeapons.tmrRotate.Enabled = false;
cLibPicTraySuspects.Visible =
cLibPicTraySuspects.tmrRotate.Enabled = false;
udrAniAccusation.bmpAccusationBoard = new Bitmap(picBoard.Image);
udrAniAccusation.bmpShadedAccusationBoard = MakeGrayscale3(udrAniAccusation.bmpAccusationBoard);
/// draw accusing suspect and bubble onto base image
Bitmap bmpAccusingSuspectImageAndBubble = getAccusingSuspectAndBubbleImage((enuSuspects)intSuspectTurn, udrAniAccusation.udrAccusation);
bmpAccusingSuspectImageAndBubble.MakeTransparent(Color.White);
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpAccusationBoard))
g.DrawImage(bmpAccusingSuspectImageAndBubble, new Point(0, 0));
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpShadedAccusationBoard))
g.DrawImage(bmpAccusingSuspectImageAndBubble, new Point(0, 0));
int intImageSize = 200;
int intSpaceBetweenRestingImages = (int)(intImageSize * .84);
int intEndTop = (int)(intImageSize * .55);
int intMaxSteps = 20;
udrAniAccusation.udrElements = new udtAnimationInfo[3];
// room
udrAniAccusation.udrElements[(int)enuCardType.room].ptPos =
udrAniAccusation.udrElements[(int)enuCardType.room].ptStart = new Point(-50, -50);
udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd = new Point((int)(bmpBoard.Width * .5) -intSpaceBetweenRestingImages , intEndTop);
udrAniAccusation.udrElements[(int)enuCardType.room].intMaxSteps = (int)(intMaxSteps*1.5);
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleFacing = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurning = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.room].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.room].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.room].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.room].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.room].bmpGray =MakeGrayscale3( new Bitmap(bmpRooms[(int)udrAniAccusation.udrAccusation.eRoom], intImageSize, intImageSize));
// this rectangle corrects any errors generated in resizing image that would leave a trailing line on the edges
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[(int)enuCardType.room].bmpGray))
g.DrawRectangle(new Pen(udrAniAccusation.udrElements[(int)enuCardType.room].bmpGray.GetPixel(0, 0), 2), new Rectangle(0, 0, intImageSize - 1, intImageSize - 1));
udrAniAccusation.udrElements[(int)enuCardType.room].bmpGray.MakeTransparent(udrAniAccusation.udrElements[(int)enuCardType.room].bmpGray.GetPixel(0, 0));
udrAniAccusation.udrElements[(int)enuCardType.room].bmp = new Bitmap(bmpRooms[(int)udrAniAccusation.udrAccusation.eRoom], intImageSize, intImageSize);
// this rectangle corrects any errors generated in resizing image that would leave a trailing line on the edges
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[(int)enuCardType.room].bmp))
g.DrawRectangle(new Pen(udrAniAccusation.udrElements[(int)enuCardType.room].bmp.GetPixel(0, 0), 2), new Rectangle(0, 0, intImageSize - 1, intImageSize - 1));
udrAniAccusation.udrElements[(int)enuCardType.room].bmp.MakeTransparent(udrAniAccusation.udrElements[(int)enuCardType.room].bmp.GetPixel(0, 0));
udrAniAccusation.udrElements[(int)enuCardType.room].intStep = 0;
// suspect
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptPos =
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart = new Point(bmpBoard.Width/2, -50);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd = new Point((int)(bmpBoard.Width * .5), intEndTop+20);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intMaxSteps = intMaxSteps;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleFacing = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurning = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.Suspect].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmpGray =MakeGrayscale3( new Bitmap(bmpSuspects[(int)udrAniAccusation.udrAccusation.eSuspect], intImageSize, intImageSize));
// this rectangle corrects any errors generated in resizing image that would leave a trailing line on the edges
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmpGray))
g.DrawRectangle(new Pen(udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmpGray.GetPixel(0, 0),2), new Rectangle(0, 0, intImageSize-1, intImageSize-1));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmpGray.MakeTransparent(udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmpGray.GetPixel(0, 0));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp = new Bitmap(bmpSuspects[(int)udrAniAccusation.udrAccusation.eSuspect], intImageSize, intImageSize);
// this rectangle corrects any errors generated in resizing image that would leave a trailing line on the edges
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp))
g.DrawRectangle(new Pen(udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp.GetPixel(0, 0), 2), new Rectangle(0, 0, intImageSize - 1, intImageSize - 1));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp.MakeTransparent(udrAniAccusation.udrElements[(int)enuCardType.Suspect].bmp.GetPixel(0, 0));
udrAniAccusation.udrElements[(int)enuCardType.Suspect].intStep = 0;
// weapon
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptPos =
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart = new Point(bmpBoard.Width +50, -50);
udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd = new Point((int)(bmpBoard.Width * .5) + intSpaceBetweenRestingImages , intEndTop);
udrAniAccusation.udrElements[(int)enuCardType.weapon].intMaxSteps = (int)(intMaxSteps*1.5);
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleFacing = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurning = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblAngleTurningAttenuation = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAcceleration = 0;
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelAngle = classMath.arcTan(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.weapon].dblTravelDistance = classMath.distanceBetweenTwoPoints(udrAniAccusation.udrElements[(int)enuCardType.weapon].ptEnd, udrAniAccusation.udrElements[(int)enuCardType.weapon].ptStart);
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmpGray =MakeGrayscale3( new Bitmap(bmpWeapons_PicTray[(int)udrAniAccusation.udrAccusation.eWeapon], intImageSize, intImageSize));
// this rectangle corrects any errors generated in resizing image that would leave a trailing line on the edges
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[(int)enuCardType.weapon].bmpGray))
g.DrawRectangle(new Pen(udrAniAccusation.udrElements[(int)enuCardType.weapon].bmpGray.GetPixel(0, 0), 2), new Rectangle(0, 0, intImageSize - 1, intImageSize - 1));
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmpGray.MakeTransparent(udrAniAccusation.udrElements[(int)enuCardType.weapon].bmpGray.GetPixel(0, 0));
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp = new Bitmap(bmpWeapons_PicTray[(int)udrAniAccusation.udrAccusation.eWeapon], intImageSize, intImageSize);
// this rectangle corrects any errors generated in resizing image that would leave a trailing line on the edges
using (Graphics g = Graphics.FromImage(udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp))
g.DrawRectangle(new Pen(udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp.GetPixel(0, 0), 2), new Rectangle(0, 0, intImageSize - 1, intImageSize - 1));
udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp.MakeTransparent(udrAniAccusation.udrElements[(int)enuCardType.weapon].bmp.GetPixel(0, 0));
udrAniAccusation.udrElements[(int)enuCardType.weapon].intStep = 0;
}
Bitmap bmpTemp = new Bitmap(udrAniAccusation.bmpShadedAccusationBoard);
bool bolQuitDraw = true;
using (Graphics g = Graphics.FromImage(bmpTemp))
{
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
{
udrAniAccusation.udrElements[(int)eTypeCounter].intStep++;
if (udrAniAccusation.udrElements[(int)eTypeCounter].intStep < udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps)
bolQuitDraw = false;
else
udrAniAccusation.udrElements[(int)eTypeCounter].intStep = udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps;
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X = udrAniAccusation.udrElements[(int)eTypeCounter].ptStart.X + (int)(udrAniAccusation.udrElements[(int)eTypeCounter].dblTravelDistance * ((double)udrAniAccusation.udrElements[(int)eTypeCounter].intStep / (double)udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps) * Math.Cos(udrAniAccusation.udrElements[(int)eTypeCounter].dblTravelAngle));
udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y = udrAniAccusation.udrElements[(int)eTypeCounter].ptStart.Y + (int)(udrAniAccusation.udrElements[(int)eTypeCounter].dblTravelDistance * ((double)udrAniAccusation.udrElements[(int)eTypeCounter].intStep / (double)udrAniAccusation.udrElements[(int)eTypeCounter].intMaxSteps) * Math.Sin(udrAniAccusation.udrElements[(int)eTypeCounter].dblTravelAngle));
Point ptTL = new Point(udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
g.DrawImage(udrAniAccusation.udrElements[(int)eTypeCounter].bmpGray, ptTL.X, ptTL.Y);
}
}
picBoard.Image = bmpTemp; picBoard.Refresh();
if (bolQuitDraw)
{
// draw the three elements in the foreground (base Accusation image has accusing-suspect & bubble)
// gray foreground
udrAniAccusation.bmpAccusationForegroundGray = new Bitmap(udrAniAccusation.bmpAccusationBoard.Width, udrAniAccusation.bmpAccusationBoard.Height);
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpAccusationForegroundGray))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, udrAniAccusation.bmpAccusationForegroundGray.Width, udrAniAccusation.bmpAccusationForegroundGray.Height));
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
g.DrawImage(udrAniAccusation.udrElements[(int)eTypeCounter].bmpGray, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
}
udrAniAccusation.bmpAccusationForegroundGray.MakeTransparent(Color.White);
// colored foreground
udrAniAccusation.bmpAccusationForeground = new Bitmap(udrAniAccusation.bmpAccusationBoard.Width, udrAniAccusation.bmpAccusationBoard.Height);
using (Graphics g = Graphics.FromImage(udrAniAccusation.bmpAccusationForeground))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, udrAniAccusation.bmpAccusationForeground.Width, udrAniAccusation.bmpAccusationForeground.Height));
for (enuCardType eTypeCounter = (enuCardType)0; eTypeCounter < enuCardType._numCardTypes; eTypeCounter++)
g.DrawImage(udrAniAccusation.udrElements[(int)eTypeCounter].bmp, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.X - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Width / 2, udrAniAccusation.udrElements[(int)eTypeCounter].ptPos.Y - udrAniAccusation.udrElements[(int)eTypeCounter].bmp.Height / 2);
}
udrAniAccusation.bmpAccusationForeground.MakeTransparent(Color.White);
eAccusationMode = enuAccuseAnimationMode.prepareToShowCards;
}
setDelayTimer(100);
}
Bitmap getAccusingSuspectAndBubbleImage(enuSuspects eSuspectMakingAccusation, udtMurder udrAccusation)
{
Bitmap bmpRetVal = new Bitmap(udrAniAccusation.bmpAccusationBoard.Width, udrAniAccusation.bmpAccusationBoard.Height);
using (Graphics g = Graphics.FromImage(bmpRetVal))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, bmpRetVal.Width, bmpRetVal.Height));
Rectangle recDest = new Rectangle(279, 252, 139, 100);
Rectangle recSrc = new Rectangle(0, 0, 139, 100);
Point ptSuspectTL = new Point(15, 420);
double dblSuspectImageFactor = 1.3;
int intSuspectImageSize = (int)(bmpSuspects[(int)eSuspectMakingAccusation].Width * dblSuspectImageFactor);
ptSuggestionBubbleTL = new Point(ptSuspectTL.X + intSuspectImageSize-50, 405);
recDest = new Rectangle(ptSuspectTL.X, ptSuspectTL.Y, intSuspectImageSize, intSuspectImageSize);
recSrc = new Rectangle(0, 0, bmpSuspects[(int)eSuspectMakingAccusation].Width, bmpSuspects[(int)eSuspectMakingAccusation].Height);
g.DrawImage(bmpSuspects[(int)eSuspectMakingAccusation], recDest, recSrc, GraphicsUnit.Pixel);
recDest = new Rectangle(ptSuggestionBubbleTL.X, ptSuggestionBubbleTL.Y, bmpSuggestionBubble.Width+50, bmpSuggestionBubble.Height-60);
recSrc = new Rectangle(0, 0, bmpSuggestionBubble.Width, bmpSuggestionBubble.Height);
g.DrawImage(bmpSuggestionBubble, recDest, recSrc, GraphicsUnit.Pixel);
Bitmap bmpText;
Font fnt = new System.Drawing.Font("blackadder itc", 36);
int intTop = 0;
int intVLineSpacine = 45;
int intLeftText = 75;
int intTabText = 190;
bmpText = getTextImage("I accuse",fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(udrAccusation.eSuspect.ToString(), new Font(fnt.Name, fnt.Size, FontStyle.Italic | FontStyle.Underline), udrAccusation.eSuspect == enuSuspects.MrsWhite ? Color.Gray : clrSuspects[(int)udrAccusation.eSuspect]);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intTabText, ptSuggestionBubbleTL.Y + intTop + intVLineSpacine + 10, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage("in the", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop + 2 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(udrAccusation.eRoom.ToString(), new Font(fnt.Name, fnt.Size, FontStyle.Italic | FontStyle.Underline));
recDest = new Rectangle(ptSuggestionBubbleTL.X + intTabText, ptSuggestionBubbleTL.Y + intTop + 3 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage("with the", fnt);
recDest = new Rectangle(ptSuggestionBubbleTL.X + intLeftText, ptSuggestionBubbleTL.Y + intTop + 4 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
bmpText = getTextImage(udrAccusation.eWeapon.ToString(), new Font(fnt.Name, fnt.Size, FontStyle.Italic | FontStyle.Underline));
recDest = new Rectangle(ptSuggestionBubbleTL.X + intTabText, ptSuggestionBubbleTL.Y + intTop + 5 * intVLineSpacine, bmpText.Width, bmpText.Height);
recSrc = new Rectangle(0, 0, bmpText.Width, bmpText.Height);
g.DrawImage(bmpText, recDest, recSrc, GraphicsUnit.Pixel);
}
return bmpRetVal;
}
public void Accuse(enuSuspects eSuspectAccusing, udtMurder udrAccusation)
{
if (eMode != enuMode.Accuse)
{
udrAniAccusation.eRestoreMode = eMode;
eMode = enuMode.Accuse;
}
btnAccuse.Enabled = pnlControls.Enabled = true;
udrAniAccusation.udrAccusation.eRoom = udrAccusation.eRoom;
udrAniAccusation.udrAccusation.eWeapon = udrAccusation.eWeapon;
udrAniAccusation.udrAccusation.eSuspect= udrAccusation.eSuspect;
eAccusationMode = enuAccuseAnimationMode.drawAccusation;
}
enuAccuseAnimationMode eAccusationMode
{
get { return udrAniAccusation._eMode; }
set
{
if (udrAniAccusation._eMode != value)
{
udrAniAccusation._eMode = value;
switch (udrAniAccusation._eMode)
{
case enuAccuseAnimationMode.drawAccusation:
udrAniAccusation.bolInit = false;
setDelayTimer(10);
break;
case enuAccuseAnimationMode.prepareToShowCards:
udrAniAccusation.bolInit = false;
setDelayTimer(10);
break;
case enuAccuseAnimationMode.showCards:
udrAniAccusation.bolInit = false;
break;
case enuAccuseAnimationMode.hideCards:
udrAniAccusation.bolInit = false;
break;
case enuAccuseAnimationMode.retractCards:
udrAniAccusation.bolInit = false;
break;
case enuAccuseAnimationMode.withdrawAccusingSuspect:
udrAniAccusation.bolInit = false;
break;
case enuAccuseAnimationMode.showNewspaper:
udrAniAccusation.bolInit = false;
setDelayTimer(10);
break;
}
}
}
}
void ShowAccuseOptions()
{
#region "init tray : cLibPicTraySuspects"
{
cLibPicTraySuspects.Options.Mirror = PicTray.enuMirror.none;
cLibPicTraySuspects.Options.makeImagesTransparent = true;
cLibPicTraySuspects.Options.PopUpClickPic = false;
cLibPicTraySuspects.Options.SelectionMode = PicTray.enuSelectionMode.click;
cLibPicTraySuspects.Options.TrayCenter = new Point(-3, 144);
cLibPicTraySuspects.Options.Width = 355;
cLibPicTraySuspects.Options.Height = 422;
cLibPicTraySuspects.Options.Rotation.StepSize = 0.120951317163207;
cLibPicTraySuspects.Options.Rotation.Interval = 27;
cLibPicTraySuspects.Options.Rotation.Mode = PicTray.enuRotationMode.toSelected;
cLibPicTraySuspects.Options.Ellipse.Angle = 1.77499984927823;
cLibPicTraySuspects.Options.Ellipse.Radius_Height = 102;
cLibPicTraySuspects.Options.Ellipse.Radius_Width = 119;
cLibPicTraySuspects.Options.Front.Angle = 0.0816814089933346;
cLibPicTraySuspects.Options.Front.UserSet = PicTray.enuFrontUserSet.none;
cLibPicTraySuspects.Options.ImageSize.Height_MinMax = new PicTray.classMinMax(75, 250);
cLibPicTraySuspects.Options.ImageSize.Width_MinMax = new PicTray.classMinMax(75, 151);
cLibPicTraySuspects.Options.ImageSize.Size_Control = enuSizeControl.both;
cLibPicTraySuspects.Options.Caption.Show = false;
cLibPicTraySuspects.Options.Caption.Font = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
cLibPicTraySuspects.Options.Caption.ForeColor = Color.FromArgb(255, 255, 255, 0);
cLibPicTraySuspects.Options.Caption.BackColor = Color.FromArgb(255, 0, 0, 0);
cLibPicTraySuspects.Left = picBoard.Left;
cLibPicTraySuspects.Top = 0;
}
#endregion
#region "init tray : cLibPicTrayWeapons"
{
cLibPicTrayWeapons.Options.Mirror = PicTray.enuMirror.horizontal;
cLibPicTrayWeapons.Options.makeImagesTransparent = true;
cLibPicTrayWeapons.Options.PopUpClickPic = false;
cLibPicTrayWeapons.Options.SelectionMode = PicTray.enuSelectionMode.click;
cLibPicTrayWeapons.Options.TrayCenter = new Point(-3, 144);
cLibPicTrayWeapons.Options.Width = 355;
cLibPicTrayWeapons.Options.Height = 422;
cLibPicTrayWeapons.Options.Rotation.StepSize = 0.120951317163207;
cLibPicTrayWeapons.Options.Rotation.Interval = 27;
cLibPicTrayWeapons.Options.Rotation.Mode = PicTray.enuRotationMode.toSelected;
cLibPicTrayWeapons.Options.Ellipse.Angle = 1.77499984927823;
cLibPicTrayWeapons.Options.Ellipse.Radius_Height = 102;
cLibPicTrayWeapons.Options.Ellipse.Radius_Width = 119;
cLibPicTrayWeapons.Options.Front.Angle = 0.0816814089933346;
cLibPicTrayWeapons.Options.Front.UserSet = PicTray.enuFrontUserSet.none;
cLibPicTrayWeapons.Options.ImageSize.Height_MinMax = new PicTray.classMinMax(75, 250);
cLibPicTrayWeapons.Options.ImageSize.Width_MinMax = new PicTray.classMinMax(75, 151);
cLibPicTrayWeapons.Options.ImageSize.Size_Control = enuSizeControl.both;
cLibPicTrayWeapons.Options.Caption.Show = false;
cLibPicTrayWeapons.Options.Caption.Font = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
cLibPicTrayWeapons.Options.Caption.ForeColor = Color.FromArgb(255, 255, 255, 0);
cLibPicTrayWeapons.Options.Caption.BackColor = Color.FromArgb(255, 0, 0, 0);
cLibPicTrayWeapons.Left = cLibPicTraySuspects.Left + cLibPicTraySuspects.Width;
cLibPicTrayWeapons.Top = 0;
}
#endregion
#region "init tray : cLibPicTrayRooms"
cLibPicTrayRooms.Options.Mirror = PicTray.enuMirror.vertical;
cLibPicTrayRooms.Options.makeImagesTransparent = false;
cLibPicTrayRooms.Options.PopUpClickPic = false;
cLibPicTrayRooms.Options.SelectionMode = PicTray.enuSelectionMode.click;
cLibPicTrayRooms.Options.TrayCenter = new Point(350, 100);
cLibPicTrayRooms.Options.Width = 705;
cLibPicTrayRooms.Options.Height = 289;
cLibPicTrayRooms.Options.Rotation.StepSize = 0.117809724509617;
cLibPicTrayRooms.Options.Rotation.Interval = 27;
cLibPicTrayRooms.Options.Rotation.Mode = PicTray.enuRotationMode.toSelected;
cLibPicTrayRooms.Options.Ellipse.Angle = 0;
cLibPicTrayRooms.Options.Ellipse.Radius_Height = 66;
cLibPicTrayRooms.Options.Ellipse.Radius_Width = 290;
cLibPicTrayRooms.Options.Front.Angle = 1.49225651045515;
cLibPicTrayRooms.Options.Front.UserSet = PicTray.enuFrontUserSet.none;
cLibPicTrayRooms.Options.ImageSize.Height_MinMax = new PicTray.classMinMax(50, 250);
cLibPicTrayRooms.Options.ImageSize.Width_MinMax = new PicTray.classMinMax(50, 150);
cLibPicTrayRooms.SizeControl = enuSizeControl.both;
cLibPicTrayRooms.Options.Caption.Show = false;
cLibPicTrayRooms.Options.Caption.Font = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
cLibPicTrayRooms.Options.Caption.ForeColor = Color.FromArgb(255, 255, 255, 0);
cLibPicTrayRooms.Options.Caption.BackColor = Color.FromArgb(255, 0, 0, 0);
cLibPicTrayRooms.Top = cLibPicTraySuspects.Top + cLibPicTraySuspects.Height;
cLibPicTrayRooms.Left = 0;
#endregion
cLibPicTrayRooms.SendToBack();
cLibPicTraySuspects.SendToBack();
cLibPicTrayWeapons.SendToBack();
cLibPicTrayRooms.Visible = true;
cLibPicTraySuspects.Visible = true;
cLibPicTrayWeapons.Visible = true;
setPicTrayBackgroundImage(ref cLibPicTrayRooms);
setPicTrayBackgroundImage(ref cLibPicTraySuspects);
setPicTrayBackgroundImage(ref cLibPicTrayWeapons);
cLibPicTrayRooms.BringToFront();
cLibPicTraySuspects.BringToFront();
cLibPicTrayWeapons.BringToFront();
btnAccuse_Ok.Top = cLibPicTrayRooms.Top - btnAccuse_Ok.Height + 40;
btnAccuse_Ok.Left = (bmpBoard.Width - btnAccuse_Ok.Width) / 2;
btnAccuse_Ok.Visible = true;
}
#endregion
void setPicTrayBackgroundImage(ref classPicTray_V2 cLibTray)
{
Bitmap bmpTempTwo = new Bitmap(cLibTray.Width, cLibTray.Height);
using (Graphics g = Graphics.FromImage(bmpTempTwo))
{
Rectangle recSrc = new Rectangle(cLibTray.Location, cLibTray.Size);
Rectangle recDest = new Rectangle(0, 0, cLibTray.Width, cLibTray.Height);
g.DrawImage((Bitmap)picBoard.Image, recDest, recSrc, GraphicsUnit.Pixel);
}
cLibTray.BackgroundImage = bmpTempTwo;
cLibTray.RefreshTrayImage();
cLibTray.Refresh();
}
public void GameOver()
{
eMode = enuMode.gameOver;
grbControls.Enabled = false;
Bitmap bmpGameOver = new Bitmap(bmpGameBoard);
Bitmap bmpBanner =new Bitmap( Clue_CS2010.Properties.Resources.Winner);
bmpBanner.MakeTransparent();
Bitmap bmpFace = new Bitmap((int)(bmpSuspects[intSuspectTurn].Width), (int)(bmpSuspects[intSuspectTurn].Height));
using (Graphics g = Graphics.FromImage(bmpFace))
{
g.FillRectangle(new SolidBrush(bmpSuspects[intSuspectTurn].GetPixel(bmpSuspects[intSuspectTurn].Width / 2, 0)), new Rectangle(0, 0, bmpFace.Width, bmpFace.Height));
g.DrawImage(bmpSuspects[intSuspectTurn], new Rectangle (0,0, bmpFace.Width, bmpFace.Height), new Rectangle(0,0, bmpSuspects[intSuspectTurn].Width, bmpSuspects[intSuspectTurn].Height), GraphicsUnit.Pixel);
}
bmpFace.MakeTransparent(bmpFace.GetPixel(0, 0));
using (Graphics g = Graphics.FromImage(bmpGameOver))
{
// draw face
double dblSizeFactor = 2.1;
Size szFace= new System.Drawing.Size((int)(bmpFace.Width *dblSizeFactor), (int)(bmpFace.Height *dblSizeFactor));
Rectangle recDest = new Rectangle((bmpGameOver.Width - szFace.Width) / 2, (bmpGameOver.Height - szFace.Height)/2, szFace.Width, szFace.Height);
Rectangle recSrc = new Rectangle(0, 0, bmpFace.Width, bmpFace.Height);
g.DrawImage(bmpFace, recDest, recSrc, GraphicsUnit.Pixel);
// draw banner
recDest = new Rectangle((bmpGameOver.Width - bmpBanner.Width) / 2, (int)(bmpGameOver.Height *.6), bmpBanner.Width, bmpBanner.Height);
recSrc = new Rectangle(0, 0, bmpBanner.Width, bmpBanner.Height);
g.DrawImage(bmpBanner, recDest, recSrc, GraphicsUnit.Pixel);
}
setDelayTimer(20000);
pnlNotebook.BringToFront();
picBoard.Image = bmpGameOver; picBoard.Refresh();
}
public void showAllowableMoves()
{
eMode = enuMode.showAllowableMoves;
pnlControls.Enabled = btnEndTurn.Enabled = cSuspects[intSuspectTurn].setAllowableMoves();
drawBoard();
}
void drawBoard()
{
bmpGameBoard = new Bitmap(bmpBoard);
classSuspect cS = cSuspects[intSuspectTurn];
Pen pTrim = new Pen(clrSuspects[intSuspectTurn], 4);
Pen pWhite = new Pen(Color.White, 1);
using (Graphics g = Graphics.FromImage(bmpGameBoard))
{
// draw allowable moves
for (int intX = 0; intX < sz.Width; intX++)
{
for (int intY = 0; intY < sz.Height; intY++)
{
if (cS.cSEAllowableMoves[intX, intY] != null)
{
g.DrawRectangle(pWhite, new Rectangle(ptBoardTL.X + intX * 28 + 3, ptBoardTL.Y + intY * 28 + 3, 22, 22));
g.DrawRectangle(pTrim, new Rectangle(ptBoardTL.X + intX * 28 + 6, ptBoardTL.Y + intY * 28 + 6, 17, 17));
g.DrawRectangle(pWhite, new Rectangle(ptBoardTL.X + intX * 28 + 8, ptBoardTL.Y + intY * 28 + 8, 12, 12));
}
}
}
// draw center back of card
Point ptCenter = getRoomCenter(enuRooms._numRooms);
Point ptTLCard = new Point(ptCenter.X - cCardUnknown.cBmp.getImage(0).Width / 2, ptCenter.Y - cCardUnknown.cBmp.getImage(0).Height / 2);
Rectangle recDestCard = new Rectangle(ptTLCard, cCardUnknown.cBmp.getImage(0).Size);
Rectangle recSrcCard = new Rectangle(0, 0, cCardUnknown.cBmp.getImage(0).Width, cCardUnknown.cBmp.getImage(0).Height);
g.DrawImage(cCardUnknown.cBmp.getImage(0), recDestCard, recSrcCard, GraphicsUnit.Pixel);
// draw weapons
Size szWeapon = new System.Drawing.Size(35, 35);
Rectangle recSrc = new Rectangle(0, 0, bmpWeapons_Board[0].Width, bmpWeapons_Board[0].Height);
for (enuWeapons eWeaponCounter = (enuWeapons)0; eWeaponCounter < enuWeapons._numWeapons; eWeaponCounter++)
{
if (cWeapons[(int)eWeaponCounter].eRoom != enuRooms.start
&& !(eMode == enuMode.animateSummonWeapon && eWeaponCounter == udrSuggestion.eWeapon)) // do not draw the weapon if it is being animated in 'summon weapon' mode
{ // in a room
Point ptPieceCenter = getWeaponGraphicPositionInRoom(eWeaponCounter);
Point ptPieceTL = new Point(ptPieceCenter.X - szWeapon.Width / 2, ptPieceCenter.Y - szWeapon.Height / 2);
Rectangle recDest = new Rectangle(ptPieceTL, szWeapon);
g.DrawImage(new Bitmap(bmpWeapons_Board[(int)eWeaponCounter]), recDest, recSrc, GraphicsUnit.Pixel);
}
}
// draw pieces
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
if (!(eMode == enuMode.animateSummonSuspect && eSuspectCounter == udrSuggestion.eSuspect)// do not draw the suspect if it is being animated in 'summon suspect' mode
&& !(eMode == enuMode.animateSecretPassage && eSuspectCounter == (enuSuspects)intSuspectTurn)) // do not draw the suspect if it is being animated in 'secret passage' mode
{
if (cSuspects[(int)eSuspectCounter].eRoom == enuRooms.tiles)
{ // on a tile
g.DrawImage(bmpPieces[(int)eSuspectCounter], new Point(ptBoardTL.X + cSuspects[(int)eSuspectCounter].ptTile.X * 28 + 2, ptBoardTL.Y + cSuspects[(int)eSuspectCounter].ptTile.Y * 28 + 2));
}
else if (cSuspects[(int)eSuspectCounter].eRoom != enuRooms.start)
{ // in a room
Point ptPieceCenter = getPieceGraphicPositionInRoom(eSuspectCounter);
Point ptPieceTL = new Point(ptPieceCenter.X - bmpPieces[(int)eSuspectCounter].Width / 2, ptPieceCenter.Y - bmpPieces[(int)eSuspectCounter].Height / 2);
g.DrawImage(bmpPieces[(int)eSuspectCounter], ptPieceTL);
}
}
}
}
picBoard.Image = bmpGameBoard; picBoard.Refresh();
}
private void btnSuggestion_Click(object sender, EventArgs e)
{
if (cSuspects[intSuspectTurn].bolPlayerControlled && !cSuspects[intSuspectTurn].bolEliminated)
eMode = enuMode.Suggest;
}
public void Suggest()
{
btnSuggest.Enabled = false;
pnlControls.Enabled = false;
drawBoard();
#region "cLibPicTraySuspects make suggestion"
cLibPicTraySuspects.Location = new Point(0, 0);
cLibPicTraySuspects.Options.Mirror = PicTray.enuMirror.none;
cLibPicTraySuspects.Options.makeImagesTransparent = true;
cLibPicTraySuspects.Options.PopUpClickPic = false;
cLibPicTraySuspects.Options.SelectionMode = PicTray.enuSelectionMode.click;
cLibPicTraySuspects.Options.TrayCenter = new Point(47, 193);
cLibPicTraySuspects.Options.Width = 355;
cLibPicTraySuspects.Options.Height = 385;
cLibPicTraySuspects.Options.Rotation.StepSize = 0.119380520836412;
cLibPicTraySuspects.Options.Rotation.Interval = 27;
cLibPicTraySuspects.Options.Rotation.Mode = PicTray.enuRotationMode.toSelected;
cLibPicTraySuspects.Options.Ellipse.Angle = 1.21579635693925;
cLibPicTraySuspects.Options.Ellipse.Radius_Height = 67;
cLibPicTraySuspects.Options.Ellipse.Radius_Width = 126;
cLibPicTraySuspects.Options.Front.Angle = 0;
cLibPicTraySuspects.Options.Front.UserSet = PicTray.enuFrontUserSet.none;
cLibPicTraySuspects.Options.ImageSize.Height_MinMax = new PicTray.classMinMax(50, 150);
cLibPicTraySuspects.Options.ImageSize.Width_MinMax = new PicTray.classMinMax(50, 150);
cLibPicTraySuspects.Options.Caption.Show = false;
cLibPicTraySuspects.Options.Caption.Font = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
cLibPicTraySuspects.Options.Caption.ForeColor = Color.FromArgb(255, 255, 255, 0);
cLibPicTraySuspects.Options.Caption.BackColor = Color.FromArgb(255, 0, 0, 0);
cLibPicTraySuspects.tmrRotate.Enabled = true;
#endregion
#region "cLibPicTrayWeapons make suggestion"
cLibPicTrayWeapons.Options.BackColor = Color.Transparent;
cLibPicTrayWeapons.Options.Mirror = PicTray.enuMirror.horizontal;
cLibPicTrayWeapons.Options.makeImagesTransparent = true;
cLibPicTrayWeapons.Options.PopUpClickPic = false;
cLibPicTrayWeapons.Options.SelectionMode = PicTray.enuSelectionMode.click;
cLibPicTrayWeapons.Options.TrayCenter = new Point(60, 210);
cLibPicTrayWeapons.Options.Width = 355;
cLibPicTrayWeapons.Options.Height = 385;
cLibPicTrayWeapons.Options.Rotation.StepSize = 0.119380520836412;
cLibPicTrayWeapons.Options.Rotation.Interval = 27;
cLibPicTrayWeapons.Options.Rotation.Mode = PicTray.enuRotationMode.toSelected;
cLibPicTrayWeapons.Options.Ellipse.Angle = 1.01579635693925;// 1.21579635693925;
cLibPicTrayWeapons.Options.Ellipse.Radius_Height = 67;
cLibPicTrayWeapons.Options.Ellipse.Radius_Width = 126;
cLibPicTrayWeapons.Options.Front.Angle = 0;
cLibPicTrayWeapons.Options.Front.UserSet = PicTray.enuFrontUserSet.none;
cLibPicTrayWeapons.Options.ImageSize.Height_MinMax = new PicTray.classMinMax(50, 150);
cLibPicTrayWeapons.Options.ImageSize.Width_MinMax = new PicTray.classMinMax(50, 150);
cLibPicTrayWeapons.Options.Caption.Show = false;
cLibPicTrayWeapons.Options.Caption.Font = new Font("Microsoft Sans Serif", (float)8.25, FontStyle.Regular);
cLibPicTrayWeapons.Options.Caption.ForeColor = Color.FromArgb(255, 255, 255, 0);
cLibPicTrayWeapons.Options.Caption.BackColor = Color.FromArgb(255, 0, 0, 0);
cLibPicTrayWeapons.tmrRotate.Enabled = true;
#endregion
DrawSuggestingSuspect();
writeSuggestion();
setUpCLibPicTrayChooseSuspect();
setUpCLibPicTrayChooseWeapon();
picBoard.Refresh();
}
void DrawRespondingSuspect(enuSuspects eSuspectResponding)
{
Bitmap bmpTemp = new Bitmap(bmpSuggestionBoard);
ptResponseBubbleTL = new Point(50, 0);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.DrawImage(bmpSuspects[(int)eSuspectResponding], new Rectangle(ptResponseBubbleTL.X + bmpResponseBubble.Width, 0, 220, 220), new Rectangle(0, 0, bmpSuspects[(int)eSuspectResponding].Width, bmpSuspects[(int)eSuspectResponding].Height), GraphicsUnit.Pixel);
g.DrawImage(bmpResponseBubble, ptResponseBubbleTL);
}
if (cButtons[(int)enuButtons.RespondToSuggestion_Ok] == null)
cButtons[(int)enuButtons.RespondToSuggestion_Ok] = new classButton(this,
ref picBoard,
enuMode.respondToSuggestion,
new Point(ptResponseBubbleTL.X + bmpResponseBubble.Width - 120, ptResponseBubbleTL.Y + bmpResponseBubble.Height - 50),
Color.Black,
"Ok",
new Font("blackadder itc", 26));
picBoard.Image = bmpTemp; picBoard.Refresh();
cButtons[(int)enuButtons.RespondToSuggestion_Ok].eButtonName = enuButtons.RespondToSuggestion_Ok;
cButtons[(int)enuButtons.RespondToSuggestion_Ok].draw();
autoProceedEnabled = bolAutoProceed;
}
Bitmap getRoomBackGroundImage(enuRooms eRoomRequested)
{
Bitmap bmpRetVal = new Bitmap(139, 100);
Rectangle recDest = new Rectangle(0, 0, 139, 100);
Point ptRoomBackground = new Point(0, 0);
switch (cSuspects[intSuspectTurn].eRoom)
{
case enuRooms.Study:
ptRoomBackground = new Point(41, 17);
break;
case enuRooms.Hall:
ptRoomBackground = new Point(288, 52);
break;
case enuRooms.Lounge:
ptRoomBackground = new Point(530, 38);
break;
case enuRooms.DiningRoom:
ptRoomBackground = new Point(519, 280);
break;
case enuRooms.Kitchen:
ptRoomBackground = new Point(544, 530);
break;
case enuRooms.BallRoom:
ptRoomBackground = new Point(293, 513);
break;
case enuRooms.Conservatory:
ptRoomBackground = new Point(39, 568);
break;
case enuRooms.BilliardRoom:
ptRoomBackground = new Point(37, 356);
break;
case enuRooms.Library:
ptRoomBackground = new Point(55, 195);
break;
}
Rectangle recSrc = new Rectangle(ptRoomBackground.X, ptRoomBackground.Y, 139, 100);
using (Graphics g = Graphics.FromImage(bmpRetVal))
g.DrawImage(bmpBoard, recDest, recSrc, GraphicsUnit.Pixel);
return bmpRetVal;
}
void DrawSuggestingSuspect()
{
Bitmap bmpTemp = new Bitmap(picBoard.Image);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
Rectangle recDest = new Rectangle(279, 252, 139, 100);
Rectangle recSrc = new Rectangle(0,0, 139, 100);
g.DrawImage(getRoomBackGroundImage(cSuspects[intSuspectTurn].eRoom), recDest, recSrc, GraphicsUnit.Pixel);
Size szWeapon = new System.Drawing.Size(35, 35);
recSrc = new Rectangle(0, 0, bmpWeapons_Board[0].Width, bmpWeapons_Board[0].Height);
for (enuWeapons eWeaponCounter = 0; eWeaponCounter < enuWeapons._numWeapons; eWeaponCounter++)
{
if (cWeapons[(int)eWeaponCounter].eRoom == enuRooms._numRooms)
{ // at center of map -> draw on top of room image
Point ptPieceCenter = getWeaponGraphicPositionInRoom(eWeaponCounter);
Point ptPieceTL = new Point(ptPieceCenter.X - szWeapon.Width / 2, ptPieceCenter.Y - szWeapon.Height / 2);
recDest = new Rectangle(ptPieceTL, szWeapon);
g.DrawImage(new Bitmap(bmpWeapons_Board[(int)eWeaponCounter]), recDest, recSrc, GraphicsUnit.Pixel);
}
}
Point ptSuspectTL = new Point(0, 400);
double dblSuspectImageFactor = 2;
int intSuspectImageSize = (int)(bmpSuspects[intSuspectTurn].Width * dblSuspectImageFactor);
ptSuggestionBubbleTL = new Point(ptSuspectTL.X + intSuspectImageSize - 50, 365);
recDest = new Rectangle(ptSuspectTL.X, ptSuspectTL.Y, intSuspectImageSize, intSuspectImageSize);
recSrc = new Rectangle(0, 0, bmpSuspects[intSuspectTurn].Width, bmpSuspects[intSuspectTurn].Height);
g.DrawImage(bmpSuspects[intSuspectTurn], recDest, recSrc, GraphicsUnit.Pixel);
recDest = new Rectangle(ptSuggestionBubbleTL.X, ptSuggestionBubbleTL.Y, bmpSuggestionBubble.Width, bmpSuggestionBubble.Height);
recSrc = new Rectangle(0, 0, bmpSuggestionBubble.Width, bmpSuggestionBubble.Height);
g.DrawImage(bmpSuggestionBubble, recDest, recSrc, GraphicsUnit.Pixel);
}
picBoard.Image = bmpTemp;
Font fntButtons = new Font("blackadder itc", 26);
if (cButtons[(int)enuButtons.MakeSuggestion_Cancel] == null)
cButtons[(int)enuButtons.MakeSuggestion_Cancel] = new classButton(this,
ref picBoard,
enuMode.Suggest,
new Point(ptSuggestionBubbleTL.X + 225, ptSuggestionBubbleTL.Y + 290),
Color.Black,
"Cancel",
fntButtons);
if (cSuspects[intSuspectTurn].bolPlayerControlled)
cButtons[(int)enuButtons.MakeSuggestion_Cancel].draw();
if (cButtons[(int)enuButtons.MakeSuggestion_Ok] == null)
cButtons[(int)enuButtons.MakeSuggestion_Ok] = new classButton(this,
ref picBoard,
enuMode.Suggest,
new Point(cButtons[(int)enuButtons.MakeSuggestion_Cancel].pt.X + cButtons[(int)enuButtons.MakeSuggestion_Cancel].sz.Width + 5,
cButtons[(int)enuButtons.MakeSuggestion_Cancel].pt.Y),
Color.Black,
"Ok",
fntButtons);
if (cSuspects[intSuspectTurn].bolPlayerControlled)
cButtons[(int)enuButtons.MakeSuggestion_Ok].draw(); ;
}
public void selectedSuspectChange()
{
setBtnChooseSuspectColorAndText();
}
private void btnEndTurn_Click(object sender, EventArgs e)
{
if (cSuspects[intSuspectTurn].bolPlayerControlled && !cSuspects[intSuspectTurn].bolEliminated)
eMode = enuMode.endTurn;
}
void drawPlayerCards()
{
Bitmap bmpNotes = new Bitmap(picNotebook.Image);
using (Graphics g = Graphics.FromImage(bmpNotes))
{
double dblAspectRatioXOverY = ((double)cCards[0].cBmp.getImage(0).Width / (double)cCards[0].cBmp.getImage(0).Height);
int intHeight = 24;
int intWidth = (int)((double)intHeight * dblAspectRatioXOverY);
classSuspect cSuspectPlayer = getPlayerSuspect();
for (int intCardCounter = 0; intCardCounter < cSuspects[intSuspectTurn].cCards.Length; intCardCounter++)
{
Point ptDest = new Point(2, cPlayerNotes[0, (int)cSuspectPlayer.cCards[intCardCounter].eCardName].pt.Y);
Size szDest = new System.Drawing.Size(intWidth, intHeight);
Rectangle recDest = new Rectangle(ptDest, szDest);
Rectangle recSrc = new Rectangle(0, 0, cCards[0].cBmp.getImage(0).Width + 1, cCards[0].cBmp.getImage(0).Height + 1);
g.DrawImage(cSuspectPlayer.cCards[intCardCounter].cBmp.getImage(0), recDest, recSrc, GraphicsUnit.Pixel);
}
}
picNotebook.Image = bmpNotebook = bmpNotes; picNotebook.Refresh();
}
classSuspect getPlayerSuspect()
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
if (cSuspects[(int)eSuspectCounter].bolPlayerControlled)
return cSuspects[(int)eSuspectCounter];
return cSuspects[0];
}
#region "roll die"
public void rollDie()
{
btnRollDie.Enabled = false;
eMode = enuMode.rollDie_begin;
udrRollDieInfo.intDieValue = 0;
udrRollDieInfo.intDieWidth = 50;
udrRollDieInfo.intMaxVel = 6;
udrRollDieInfo.intVelFactor = 20;
udrRollDieInfo.dblVelocityAttenuationFactor = 0.90;
udrRollDieInfo.intRightMost = picDieBox.Width;
udrRollDieInfo.intLowerMost = picDieBox.Height;
cSuspects[intSuspectTurn].bolCanSuggest = false;
udrRollDieInfo.dblVel = (double)(udrRollDieInfo.intMaxVel * udrRollDieInfo.intVelFactor / 2) * rnd.NextDouble() + (udrRollDieInfo.intMaxVel * udrRollDieInfo.intVelFactor / 2);
udrRollDieInfo.dblAngle = 0.0;
udrRollDieInfo.ptDie = new Point(0, 0);
switch (cSuspects[intSuspectTurn].eName)
{
case enuSuspects.MissScarlet:
udrRollDieInfo.dblAngle = 10.0 / 18.0 * Math.PI;
udrRollDieInfo.ptDie = new Point((int)(picDieBox.Width * .7 - udrRollDieInfo.intDieWidth / 2.0), 0);
break;
case enuSuspects.ColMustard:
udrRollDieInfo.dblAngle = 7.0 / 8.8 * Math.PI;
udrRollDieInfo.ptDie = new Point(picDieBox.Width - udrRollDieInfo.intDieWidth, (int)(picDieBox.Height * .4 - udrRollDieInfo.intDieWidth / 2));
break;
case enuSuspects.MrsWhite:
udrRollDieInfo.dblAngle = 26.0 / 18.0 * Math.PI;
udrRollDieInfo.ptDie = new Point((int)(picDieBox.Width * .7 - udrRollDieInfo.intDieWidth / 2), picDieBox.Height - udrRollDieInfo.intDieWidth);
break;
case enuSuspects.RevGreen:
udrRollDieInfo.dblAngle = 28.0 / 18.0 * Math.PI;
udrRollDieInfo.ptDie = new Point((int)(picDieBox.Width * .3 - udrRollDieInfo.intDieWidth / 2), picDieBox.Height - udrRollDieInfo.intDieWidth);
break;
case enuSuspects.MrsPeacock:
udrRollDieInfo.dblAngle = 35.0 / 18.0 * Math.PI;
udrRollDieInfo.ptDie = new Point(0, (int)(picDieBox.Height * .6 - udrRollDieInfo.intDieWidth / 2));
break;
case enuSuspects.ProfPlum:
udrRollDieInfo.dblAngle = 1.0 / 18.0 * Math.PI;
udrRollDieInfo.ptDie = new Point(0, (int)(picDieBox.Height * .4 - udrRollDieInfo.intDieWidth / 2));
break;
}
udrRollDieInfo.dblXVel = udrRollDieInfo.dblVel * Math.Cos(udrRollDieInfo.dblAngle);
udrRollDieInfo.dblYVel = udrRollDieInfo.dblVel * Math.Sin(udrRollDieInfo.dblAngle);
double dblStartVel = Math.Sqrt(udrRollDieInfo.dblXVel * udrRollDieInfo.dblXVel + udrRollDieInfo.dblYVel * udrRollDieInfo.dblYVel);
double dblMinVel = 2.0;
udrRollDieInfo.intRollCount = (int)(Math.Log(dblMinVel / dblStartVel) / Math.Log(udrRollDieInfo.dblVelocityAttenuationFactor));
udrRollDieInfo.intRollAnimation = 0;
//
eMode = enuMode.rollDie_animate;
}
void rollDie_animate()
{
Bitmap bmpDieBox = new Bitmap(bmpBaize,picDieBox.Size);
if (udrRollDieInfo.bmpCurrent == null)
udrRollDieInfo.bmpCurrent = cBmpDie[1].getImage(1);
Rectangle recDieSrc = new Rectangle(0, 0, udrRollDieInfo.bmpCurrent.Width, udrRollDieInfo.bmpCurrent.Height);
Rectangle recDieBox = new Rectangle(0, 0, picDieBox.Width, picDieBox.Height);
Rectangle recDieDest;
if (udrRollDieInfo.intRollAnimation < udrRollDieInfo.intRollCount)
{
udrRollDieInfo.intRollAnimation++;
udrRollDieInfo.intDieValue = (int)(rnd.NextDouble() * 1000) % 6 + 1;
int intSleepTime = 0;
using (Graphics g = Graphics.FromImage(bmpDieBox))
{
g.DrawImage(bmpBaize, recDieBox, recDieBox, GraphicsUnit.Pixel);
udrRollDieInfo.bmpCurrent = cBmpDie[udrRollDieInfo.intDieValue].getImage(udrRollDieInfo.intImageIndex);
recDieDest = new Rectangle(udrRollDieInfo.ptDie.X - udrRollDieInfo.bmpCurrent.Width / 2, udrRollDieInfo.ptDie.Y - udrRollDieInfo.bmpCurrent.Height / 2, udrRollDieInfo.bmpCurrent.Width, udrRollDieInfo.bmpCurrent.Height);
g.DrawImage(udrRollDieInfo.bmpCurrent, recDieDest, recDieSrc, GraphicsUnit.Pixel);
picDieBox.Image = bmpDieBox;
picDieBox.Refresh();
int intMinSleep = (int)((double)udrRollDieInfo.intVelFactor * (double)udrRollDieInfo.intMaxVel) + 1;
intSleepTime = intMinSleep - (int)(Math.Sqrt(udrRollDieInfo.dblXVel * udrRollDieInfo.dblXVel + udrRollDieInfo.dblYVel * udrRollDieInfo.dblYVel));
udrRollDieInfo.intDieValue = (int)(rnd.NextDouble() * 1000) % 6 + 1;
if ((int)(rnd.NextDouble() * 1000) % intSleepTime < 300)
{
if ((int)(rnd.NextDouble() * 1000) % 2 == 0)
udrRollDieInfo.intImageIndex = (int)(udrRollDieInfo.intImageIndex + 1) % 16;
else
udrRollDieInfo.intImageIndex = (int)(udrRollDieInfo.intImageIndex + 15) % 16;
}
udrRollDieInfo.bmpCurrent = cBmpDie[udrRollDieInfo.intDieValue].getImage(udrRollDieInfo.intImageIndex);
udrRollDieInfo.dblXVel *= udrRollDieInfo.dblVelocityAttenuationFactor;
udrRollDieInfo.ptDie.X += (int)udrRollDieInfo.dblXVel;
if (udrRollDieInfo.ptDie.X - udrRollDieInfo.bmpCurrent .Width/2< 0)
{
int intDifference = udrRollDieInfo.ptDie.X - udrRollDieInfo.bmpCurrent.Width / 2;
udrRollDieInfo.ptDie.X = udrRollDieInfo.bmpCurrent.Width / 2 - intDifference;
udrRollDieInfo.dblXVel *= -1;
}
else if (udrRollDieInfo.ptDie.X + udrRollDieInfo.bmpCurrent .Width/2 > udrRollDieInfo.intRightMost)
{
int intDifference = udrRollDieInfo.intRightMost - (udrRollDieInfo.ptDie.X + udrRollDieInfo.bmpCurrent.Width / 2);
udrRollDieInfo.ptDie.X = udrRollDieInfo.intRightMost + intDifference - udrRollDieInfo.bmpCurrent.Width/2;
udrRollDieInfo.dblXVel *= -1;
}
udrRollDieInfo.dblYVel *= udrRollDieInfo.dblVelocityAttenuationFactor;
udrRollDieInfo.ptDie.Y += (int)udrRollDieInfo.dblYVel;
if (udrRollDieInfo.ptDie.Y - udrRollDieInfo.bmpCurrent.Height /2 < 0)
{
int intDifference = udrRollDieInfo.ptDie.Y - udrRollDieInfo.bmpCurrent.Height / 2;
udrRollDieInfo.ptDie.Y = udrRollDieInfo.bmpCurrent.Height / 2 - intDifference;
udrRollDieInfo.dblYVel *= -1;
}
else if (udrRollDieInfo.ptDie.Y + udrRollDieInfo.bmpCurrent.Height/2 > udrRollDieInfo.intLowerMost)
{
int intDifference = udrRollDieInfo.intLowerMost - (udrRollDieInfo.ptDie.Y + udrRollDieInfo.bmpCurrent.Height / 2);
udrRollDieInfo.ptDie.Y = udrRollDieInfo.intLowerMost - udrRollDieInfo.bmpCurrent.Height / 2 + intDifference;
udrRollDieInfo.dblYVel *= -1;
}
double dblVel = Math.Sqrt(Math.Pow(udrRollDieInfo.dblXVel, 2) + Math.Pow(udrRollDieInfo.dblYVel, 2));
if (dblVel < cBmpDie[1].getImage(0).Width)
udrRollDieInfo.intRollAnimation = udrRollDieInfo.intRollCount; // quit when moving too slow
}
setDelayTimer(intSleepTime);
return;
}
else
eMode = enuMode.rollDie_end;
}
void rollDie_End()
{
Bitmap bmpDieBox = new Bitmap(bmpBaize);
Rectangle recDieSrc = new Rectangle(0, 0, udrRollDieInfo.bmpCurrent.Width + 1, udrRollDieInfo.bmpCurrent.Height + 1);
Rectangle recDieBox = new Rectangle(0, 0, picDieBox.Width, picDieBox.Height);
Rectangle recDieDest;
using (Graphics g = Graphics.FromImage(bmpDieBox))
{
g.DrawImage(bmpBaize, recDieBox, recDieBox, GraphicsUnit.Pixel);
recDieDest = new Rectangle(udrRollDieInfo.ptDie.X - udrRollDieInfo.bmpCurrent.Width/2, udrRollDieInfo.ptDie.Y - udrRollDieInfo.bmpCurrent.Height/2, udrRollDieInfo.bmpCurrent.Width, udrRollDieInfo.bmpCurrent.Height);
g.DrawImage(udrRollDieInfo.bmpCurrent, recDieDest, recDieSrc, GraphicsUnit.Pixel);
}
picDieBox.Image = bmpDieBox;
picDieBox.Refresh();
if (!cSuspects[intSuspectTurn].bolPlayerControlled)
{
showAllowableMoves();
setDelayTimer(500);
}
else
showAllowableMoves();
}
#endregion
private void btnRollDie_Click(object sender, EventArgs e)
{
if (cSuspects[intSuspectTurn].bolPlayerControlled && !cSuspects[intSuspectTurn].bolEliminated)
{
pnlControls.Enabled = false;
rollDie();
}
}
public void ProveSuggestion()
{
// display appropriate images on pic trays
cLibPicTraySuspects.setSelectedImage((int)udrSuggestion.eSuspect);
cLibPicTraySuspects.Angle = cLibPicTraySuspects.FrontAngle - cLibPicTraySuspects.Tray[(int)udrSuggestion.eSuspect].angleOnTray;
cLibPicTraySuspects.RefreshTrayImage();
cLibPicTrayWeapons.setSelectedImage((int)udrSuggestion.eWeapon);
cLibPicTrayWeapons.Angle = cLibPicTrayWeapons.FrontAngle - cLibPicTrayWeapons.Tray[(int)udrSuggestion.eWeapon].angleOnTray;
cLibPicTrayWeapons.RefreshTrayImage();
udrSuggestionAnimation.intProveSuggestionCycleCounter = 1;
eMode = enuMode.respondToSuggestion;
cSuspects[intSuspectTurn].bolCanSuggest = false;
cSuspects[intSuspectTurn].bolHasNotYetMadeASuggestionThisTurn = true;
bmpSuggestionBoard = new Bitmap(picBoard.Image);
// erase pic trays & draw their images onto the bmpSuggestionBoard
using (Graphics g = Graphics.FromImage(bmpSuggestionBoard))
{
Rectangle recSrc, recDest;
recSrc = new Rectangle(0, 0, cLibPicTraySuspects.Width, cLibPicTraySuspects.Height);
recDest = new Rectangle(cLibPicTraySuspects.Left, cLibPicTraySuspects.Top, cLibPicTraySuspects.Width, cLibPicTraySuspects.Height);
g.DrawImage(new Bitmap(cLibPicTraySuspects.Image), recDest, recSrc, GraphicsUnit.Pixel);
cLibPicTraySuspects.Visible = false;
recSrc = new Rectangle(0, 0, cLibPicTrayWeapons.Width, cLibPicTrayWeapons.Height);
recDest = new Rectangle(cLibPicTrayWeapons.Left, cLibPicTrayWeapons.Top, cLibPicTrayWeapons.Width, cLibPicTrayWeapons.Height);
g.DrawImage(new Bitmap(cLibPicTrayWeapons.Image), recDest, recSrc, GraphicsUnit.Pixel);
cLibPicTrayWeapons.Visible = false;
}
udrSuggestionAnimation.intProveSuggestionCycleCounter = 1;
ProveSuggestion_CycleThroughSuspects();
}
void ProveSuggestion_CycleThroughSuspects()
{
// cycle through all suspects
enuSuspects eSuspectCounter = (enuSuspects)(((int)cSuspects[intSuspectTurn].eName + udrSuggestionAnimation.intProveSuggestionCycleCounter) % (int)enuSuspects._numSuspects);
if (cSuspects[(int)eSuspectCounter].bolPlayerControlled)
{
eMode = enuMode.playerChoosesCardToShow;
showPlayerResponseOptions();
return;
}
else
{
enuCards eResponse = cSuspects[(int)eSuspectCounter].RespondToSuggestion();
ProveSuggestion_ReceiveResponse(eSuspectCounter, eResponse);
}
}
void showPlayerResponseOptions()
{
eValidPlayerResponseCards = new enuCards[0];
classSuspect cPlayer = getPlayerSuspect();
enuCards eCardTemp;
eCardTemp = classCard.getECardFromERoom(udrSuggestion.eRoom);
if (eCardIsInListeCards(ref cPlayer.cCards, eCardTemp))
appendCardList(ref eValidPlayerResponseCards, eCardTemp);
eCardTemp = classCard.getECardFromESuspect(udrSuggestion.eSuspect);
if (eCardIsInListeCards(ref cPlayer.cCards, eCardTemp))
appendCardList(ref eValidPlayerResponseCards, eCardTemp);
eCardTemp = classCard.getECardFromEWeapon(udrSuggestion.eWeapon);
if (eCardIsInListeCards(ref cPlayer.cCards, eCardTemp))
appendCardList(ref eValidPlayerResponseCards, eCardTemp);
double dblBannerAspectRatioXOverY = (double)bmpBannerCardToShow.Width / (double)bmpBannerCardToShow.Height;
Point ptTLBanner = new Point(100, 135);
int intBannerWidth = bmpBoard.Width - ptTLBanner.X - 5;
int intBannerHeight = (int)(intBannerWidth / dblBannerAspectRatioXOverY);
Size szBanner = new System.Drawing.Size(intBannerWidth, intBannerHeight);
Rectangle recBanner = new Rectangle(ptTLBanner, szBanner);
Bitmap bmpBannerBackground = new Bitmap(szBanner.Width, szBanner.Height);
using (Graphics g = Graphics.FromImage(bmpBannerBackground))
{
Rectangle recDest = new Rectangle(0, 0, bmpBannerBackground.Width, bmpBannerBackground.Height);
g.DrawImage(bmpSuggestionBoard, recDest, recBanner, GraphicsUnit.Pixel);
if (eValidPlayerResponseCards.Length > 0)
{
g.DrawImage(bmpBannerCardToShow, recDest, new Rectangle(0, 0, bmpBannerCardToShow.Width, bmpBannerCardToShow.Height), GraphicsUnit.Pixel);
// player has at least one card to show
int intTop = 2;
int intHGap = 10;
int intWidth = 120;
Point[] pts = new Point[eValidPlayerResponseCards.Length];
switch (eValidPlayerResponseCards.Length)
{
case 1:
pts[0] = new Point((bmpBoard.Width - intWidth) / 2, intTop);
break;
case 2:
pts[0] = new Point(bmpBoard.Width / 2 - intWidth - intHGap, intTop);
pts[1] = new Point(bmpBoard.Width / 2 + intHGap, intTop);
break;
case 3:
pts[0] = new Point((bmpBoard.Width - intWidth) / 2, intTop);
pts[1] = new Point(pts[0].X - intWidth - intHGap, intTop);
pts[2] = new Point(pts[0].X + intWidth + intHGap, intTop);
break;
}
for (int intValidCardCounter = 0; intValidCardCounter < eValidPlayerResponseCards.Length; intValidCardCounter++)
{
double dblAspectRatioYOverX = (double)cCards[(int)eValidPlayerResponseCards[intValidCardCounter]].cBmp.getImage(0).Height / (double)cCards[(int)eValidPlayerResponseCards[intValidCardCounter]].cBmp.getImage(0).Width;
int intHeight = (int)(intWidth * dblAspectRatioYOverX);
Size szButton = new Size(intWidth, intHeight);
Bitmap bmpBackgroundImage = new Bitmap(cCards[(int)eValidPlayerResponseCards[intValidCardCounter]].cBmp.getImage(0), intWidth, intHeight);
btnPlayerResponse[intValidCardCounter].BackgroundImage = bmpBackgroundImage;
btnPlayerResponse[intValidCardCounter].Width = szButton.Width + 3;
btnPlayerResponse[intValidCardCounter].Height = szButton.Height + 3;
btnPlayerResponse[intValidCardCounter].Tag = cCards[(int)eValidPlayerResponseCards[intValidCardCounter]];
btnPlayerResponse[intValidCardCounter].Location = pts[intValidCardCounter];
btnPlayerResponse[intValidCardCounter].BringToFront();
btnPlayerResponse[intValidCardCounter].Visible = true;
btnPlayerResponse[intValidCardCounter].Refresh();
}
autoProceedEnabled = bolAutoProceed && (eValidPlayerResponseCards.Length == 1); // auto-proceed if there is only one choice
}
else
{
g.DrawImage(bmpBannerNoCard, recDest, new Rectangle(0, 0, bmpBannerNoCard.Width, bmpBannerNoCard.Height), GraphicsUnit.Pixel);
autoProceedEnabled = bolAutoProceed; //DEBUGHERE
}
}
Bitmap bmpTemp = new Bitmap(bmpSuggestionBoard);
using (Graphics g = Graphics.FromImage(bmpTemp))
g.DrawImage(bmpBannerBackground, recBanner, new Rectangle(0, 0, bmpBannerBackground.Width, bmpBannerBackground.Height), GraphicsUnit.Pixel);
recBannerButton = new Rectangle(recBanner.Left + 127, recBanner.Top + 29, 363, 68);
picBoard.Image = bmpTemp;
picBoard.Refresh();
}
void btnPlayerResponse_Click(object sender, MouseEventArgs e)
{
autoProceedEnabled = false;
picBoard.Image = bmpSuggestionBoard; picBoard.Refresh();
Button btnThis = (Button)sender;
for (int intButtonCounter = 0; intButtonCounter < btnPlayerResponse.Length; intButtonCounter++)
btnPlayerResponse[intButtonCounter].Visible = false;
classCard cCardToShow = (classCard)(btnThis.Tag);
eMode = enuMode.respondToSuggestion;
for (int intButtonCounter = 0; intButtonCounter < btnPlayerResponse.Length; intButtonCounter++)
btnPlayerResponse[intButtonCounter].Visible = false;
ProveSuggestion_ReceiveResponse(getPlayerSuspect().eName, cCardToShow.eCardName);
}
void ProveSuggestion_ReceiveResponse(enuSuspects eRespondingSuspect, enuCards eResponse)
{
DrawRespondingSuspect(eRespondingSuspect);
writeResponse(eResponse, eRespondingSuspect);
for (enuSuspects eSuspectAICounter = (enuSuspects)0; eSuspectAICounter < enuSuspects._numSuspects; eSuspectAICounter++)
{
if (!cSuspects[(int)eSuspectAICounter].bolPlayerControlled
&& eRespondingSuspect != eSuspectAICounter)
{
enuCards eCardThisAISuspectSees = eResponse;
if (eSuspectAICounter != cSuspects[intSuspectTurn].eName)
{ // this AISuspect is NOT the player who's turn it is
if (eResponse != enuCards.NoCardShown)
eCardThisAISuspectSees = enuCards.Unknown;
}
cSuspects[(int)eSuspectAICounter].ResponseToSuggestion(eRespondingSuspect, eCardThisAISuspectSees);
}
}
udrSuggestionAnimation.intProveSuggestionCycleCounter++;
if (eResponse != enuCards.NoCardShown)
{
udrSuggestionAnimation.intProveSuggestionCycleCounter = 6;
}
}
private void btnWarnPlayerWhoseTurnItIs_Click(object sender, EventArgs e)
{
btnWarnPlayerWhoseTurnItIs.Visible = false;
btnRollDie.Enabled
= grbControls.Enabled
= btnAccuse.Enabled
= true;
eMode = enuMode.beginTurn;
}
}
public class classSearchElement
{
public Point pt;
public int intSteps;
public int intTurns;
public int intCost;
public enuDir SrcDir;
public classSearchElement next;
public void set(Point PT, int Cost, enuDir sourceDirection)
{ set(PT, sourceDirection, Cost, 0); }
public void set(Point PT, enuDir sourceDirection, int Steps, int turns)
{
pt = PT;
SrcDir = sourceDirection;
intSteps = Steps;
intTurns = turns;
intCost = intTurns * 3 + intSteps;
}
}
public struct udtSearchElementQ
{
public classSearchElement head;
public classSearchElement tail;
}
public class classRoom
{
public enuRooms name;
public Point[] ptDoors;
formClue mainForm;
public classRoom(enuRooms Name, formClue MainForm)
{
mainForm = MainForm;
name = Name;
setDoors();
}
public Point[] getValidDoors() { return getValidDoors(true); }
public Point[] getValidDoors(bool bolAllowSecretDoor)
{
Point[] ptRetVal = new Point[0];
for (int intDoorCounter = 0; intDoorCounter < ptDoors.Length; intDoorCounter++)
{
if (classSuspect.cFloor[ptDoors[intDoorCounter].X, ptDoors[intDoorCounter].Y].dirDoor == enuDir.secretPassage)
{
if (bolAllowSecretDoor)
{
Array.Resize<Point>(ref ptRetVal, ptRetVal.Length + 1);
ptRetVal[ptRetVal.Length - 1] = ptDoors[intDoorCounter];
}
}
else
{
Point ptNext = mainForm.movePoint(ptDoors[intDoorCounter], classSuspect.cFloor[ptDoors[intDoorCounter].X, ptDoors[intDoorCounter].Y].dirDoor);
if (mainForm.floorTileIsFree(ptNext) || mainForm.cSuspects[mainForm.intSuspectTurn].ptTile == ptNext) // tile is free or suspect whose turn it is is standing on it
{
// doors are only valid if they are NOT BLOCKED
bool bolDoorValid = true;
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
if (eSuspectCounter != (enuSuspects)mainForm.intSuspectTurn && mainForm.cSuspects[(int)eSuspectCounter].eRoom == enuRooms.tiles)
if (mainForm.cSuspects[(int)eSuspectCounter].ptTile == ptNext)
bolDoorValid = false;
}
if (bolDoorValid)
{
Array.Resize<Point>(ref ptRetVal, ptRetVal.Length + 1);
ptRetVal[ptRetVal.Length - 1] = ptDoors[intDoorCounter];
}
}
}
}
return ptRetVal;
}
void setDoors()
{
ptDoors = new Point[0];
int intRoomID = (int)name;
for (int intX = 0; intX < mainForm.sz.Width; intX++)
for (int intY = 0; intY < mainForm.sz.Height; intY++)
{
if (classSuspect.cFloor[intX, intY].eType == enuFloor.door
&& classSuspect.cFloor[intX, intY].eRoom == name)
{
Array.Resize<Point>(ref ptDoors, ptDoors.Length + 1);
ptDoors[ptDoors.Length - 1] = new Point(intX, intY);
}
}
}
public enuRooms oppositeCornerRoom()
{
switch (name)
{
case enuRooms.Study:
return enuRooms.Kitchen;
case enuRooms.Lounge:
return enuRooms.Conservatory;
case enuRooms.Kitchen:
return enuRooms.Study;
case enuRooms.Conservatory:
return enuRooms.Lounge;
default:
return name;
}
}
}
public class classCardsCalled
{
public enuCards[] cCardsThatMightHaveBeenShown;
}
public class classSuspectCardsCalled
{
public classCardsCalled[] cSetsOfCardsCalled;
}
public class udtAILogic
{
public classSuspectCardsCalled[] cSuspectsUnknowns;
public enuNote[,] eNotes;
public enuRooms[] eRoomsLeft;
public enuWeapons[] eWeaponsLeft;
public enuSuspects[] eSuspectsLeft;
public enuRooms eDestinationRoom;
public Point ptDestinationTile;
public udtSuggestionAI udrSuggestionAI;
}
public class classTurnsReachRoom
{
public enuRooms eRoom;
int intCost;
public int getCost
{
get { return intCost; }
}
public void resetCost()
{
intCost = 1000;
}
public bool setCost(int intNewValue)
{
if (intNewValue < intCost)
{
intCost = intNewValue;
return true;
}
else
return false;
}
}
public class classSuspect
{
public bool bolPlayerControlled;
public bool bolEliminated;
bool _bolCanSuggest;
public bool bolMustMove;
public bool bolHasNotYetMadeASuggestionThisTurn;
public enuSuspects eName;
public Point ptTile;
public Point ptFirstTile;
public enuRooms eRoom;
public classCard[] cCards = new classCard[0];
public classSearchElement[,] cSEAllowableMoves;
public classSearchElement[,] cShortestPath;
static classSearchElement[] cSEArray = new classSearchElement[0];
public classTurnsReachRoom[] cNumTurnsToReachRooms = new classTurnsReachRoom[(int)enuRooms._numRooms];
public static classFloor[,] cFloor;
public enuRooms[] eRoomsIHoldACardFor;
public enuWeapons[] eWeaponsIHoldACardFor;
public enuSuspects[] eSuspectsIHoldACardFor;
public enuAILevel eAILevel = enuAILevel.average;
public udtAILogic udrAILogic;
udtSearchElementQ searchQ;
formClue MainForm;
public classSuspect(enuSuspects Name, formClue mainForm)
{
eName = Name;
MainForm = mainForm;
setFirstTiles();
if (cFloor == null)
initFloor();
bolPlayerControlled = false;
// init allowable moves table
if (cSEAllowableMoves == null)
cSEAllowableMoves = new classSearchElement[MainForm.sz.Width, MainForm.sz.Height];
}
public bool bolCanSuggest
{
get { return _bolCanSuggest; }
set
{
if (_bolCanSuggest != value)
_bolCanSuggest = value;
}
}
public void initNotes()
{
udrAILogic = new udtAILogic();
udrAILogic.eNotes = new enuNote[(int)enuSuspects._numSuspects, (int)enuCards._numCards];
udrAILogic.cSuspectsUnknowns = new classSuspectCardsCalled[(int)enuSuspects._numSuspects];
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
// init logic of suggestion responses
udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter] = new classSuspectCardsCalled();
udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled = new classCardsCalled[0];
// init notes
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
udrAILogic.eNotes[(int)eSuspectCounter, (int)eCardCounter] = (eSuspectCounter == eName ? enuNote.X : enuNote.blank);
}
// reset possible rooms
udrAILogic.eRoomsLeft = new enuRooms[(int)enuRooms._numRooms];
for (enuRooms eRoomCounter = (enuRooms)0; eRoomCounter < enuRooms._numRooms; eRoomCounter++)
udrAILogic.eRoomsLeft[(int)eRoomCounter] = eRoomCounter;
udrAILogic.eWeaponsLeft = new enuWeapons[(int)enuWeapons._numWeapons];
for (enuWeapons eWeaponCounter = (enuWeapons)0; eWeaponCounter < enuWeapons._numWeapons; eWeaponCounter++)
udrAILogic.eWeaponsLeft[(int)eWeaponCounter] = eWeaponCounter;
udrAILogic.eSuspectsLeft = new enuSuspects[(int)enuSuspects._numSuspects];
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
udrAILogic.eSuspectsLeft[(int)eSuspectCounter] = eSuspectCounter;
// init suggestionAI
udrAILogic.udrSuggestionAI.suspectMysteryInfo = new udtSuggestionAI_perSuspect[(int)enuSuspects._numSuspects - 1];
for (int intSuspectCounter = 1; intSuspectCounter < (int)enuSuspects._numSuspects; intSuspectCounter++)
{
udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter - 1].eSuspect = (enuSuspects)(((int)eName + intSuspectCounter) % (int)enuSuspects._numSuspects);
}
}
/// <summary>
/// uses the 24x24 pixel bitmap bmpClueFloor to set up 2d array describing the game map.
/// each pixel represents a square on the board.
/// the pixel color components (Red, Green, Blue) determines the type of tile.
/// Marble Tile (corridors) : R=255,
/// G=255,
/// B=255 (white).
/// Illegal square : R=0,
/// G=0,
/// B=0 (black).
/// Room : R=255,
/// G = ROOM ID NUMBER (study =0, hall =1, ... billiard room = 7, library =8),
/// B=0 (variant of Red).
/// Door : R=egress direction (0=north, 1=east, 2=south, 3=west, 4=secretpassage),
/// G=Room ID,
/// B=255 (variant of Blue).
/// e.g. the marble tile south of the door (6,4 in 2d array) to the study is white (0,0,0).
/// the first tile into the study(roomId=0) is considered a door-tile facing south(dir=2) therefore tile (6,3 in 2d array) is colored (2,0,255).
/// the top-left-most tile (0,0) is the study's secret passage to the kitchen(roomID=4) therefore its tile is colored(4,4,255).
/// the right-bottom-most tile (23,23) is the kitchen's secret passage to the Study(roomID=0) therefore its tile is colored (4,0,255).
/// </summary>
void initFloor()
{ // static floor tiles
Bitmap bmpFloorTiles = new Bitmap(Clue_CS2010.Properties.Resources.ClueFloor);
cFloor = new classFloor[bmpFloorTiles.Width, bmpFloorTiles.Height];
for (int intX = 0; intX < bmpFloorTiles.Width; intX++)
for (int intY = 0; intY < bmpFloorTiles.Height; intY++)
{
//if (intX == 0 && intY == 23)
// MessageBox.Show("stop initFloor()");
cFloor[intX, intY] = new classFloor();
Color clrTile = bmpFloorTiles.GetPixel(intX, intY);
if (clrTile.R == 255 && clrTile.G == 255 && clrTile.B == 255)
{ // white = tile
cFloor[intX, intY].eType = enuFloor.tile;
}
else if (clrTile.R == 0 && clrTile.G == 0 && clrTile.B == 0)
{ // black = invalid
cFloor[intX, intY].eType = enuFloor.invalid;
}
else if (clrTile.B == 255)
{ // blue = door : R = direction door exits room, G = roomID#
cFloor[intX, intY].eType = enuFloor.door;
cFloor[intX, intY].dirDoor = (enuDir)clrTile.R;
cFloor[intX, intY].eRoom = (enuRooms)clrTile.G;
}
else if (clrTile.R == 255)
{ // red = room : G = roomID#
cFloor[intX, intY].eType = enuFloor.room;
cFloor[intX, intY].eRoom = (enuRooms)clrTile.G;
}
else
MessageBox.Show("this should not happen");
}
}
void disposeSE(ref classSearchElement cSE)
{
Array.Resize<classSearchElement>(ref cSEArray, cSEArray.Length + 1);
cSEArray[cSEArray.Length - 1] = cSE;
}
classSearchElement getSE()
{
classSearchElement cSERetVal;
if (cSEArray.Length > 0)
{
cSERetVal = cSEArray[cSEArray.Length - 1];
Array.Resize<classSearchElement>(ref cSEArray, cSEArray.Length - 1);
}
else
{
cSERetVal = new classSearchElement();
}
return cSERetVal;
}
public void resetAllowableMoves()
{
// reset allowable moves table
for (int intX = 0; intX < MainForm.sz.Width; intX++)
for (int intY = 0; intY < MainForm.sz.Height; intY++)
{
if (cSEAllowableMoves[intX, intY] != null)
{
disposeSE(ref cSEAllowableMoves[intX, intY]);
cSEAllowableMoves[intX, intY] = null;
}
}
}
public void allowSecretPassage()
{
// if in a corner room -> set allowable secret passage
switch (eRoom)
{
case enuRooms.Study:
Point ptStudySecretPassage = new Point(0, 0);
cSEAllowableMoves[ptStudySecretPassage.X, ptStudySecretPassage.Y] = getSE();
cSEAllowableMoves[ptStudySecretPassage.X, ptStudySecretPassage.Y].set(ptStudySecretPassage, 0, enuDir.secretPassage);
break;
case enuRooms.Lounge:
Point ptLoungeSecretPassage = new Point(MainForm.sz.Width - 1, 0);
cSEAllowableMoves[ptLoungeSecretPassage.X, ptLoungeSecretPassage.Y] = getSE();
cSEAllowableMoves[ptLoungeSecretPassage.X, ptLoungeSecretPassage.Y].set(ptLoungeSecretPassage, 0, enuDir.secretPassage);
break;
case enuRooms.Kitchen:
Point ptKitchenSecretPassage = new Point(MainForm.sz.Width - 1, MainForm.sz.Height - 1);
cSEAllowableMoves[ptKitchenSecretPassage.X, ptKitchenSecretPassage.Y] = getSE();
cSEAllowableMoves[ptKitchenSecretPassage.X, ptKitchenSecretPassage.Y].set(ptKitchenSecretPassage, 0, enuDir.secretPassage);
break;
case enuRooms.Conservatory:
Point ptConservatorySecretPassage = new Point(0, MainForm.sz.Height - 1);
cSEAllowableMoves[ptConservatorySecretPassage.X, ptConservatorySecretPassage.Y] = getSE();
cSEAllowableMoves[ptConservatorySecretPassage.X, ptConservatorySecretPassage.Y].set(ptConservatorySecretPassage, 0, enuDir.secretPassage);
break;
}
}
void resetShortestPath()
{
if (cShortestPath == null)
{
cShortestPath = new classSearchElement[MainForm.sz.Width, MainForm.sz.Height];
}
for (int intX = 0; intX < MainForm.sz.Width; intX++)
for (int intY = 0; intY < MainForm.sz.Height; intY++)
{
if (cShortestPath[intX, intY] != null)
{
disposeSE(ref cShortestPath[intX, intY]);
cShortestPath[intX, intY] = null;
}
}
cNumTurnsToReachRooms = new classTurnsReachRoom[(int)enuRooms._numRooms];
for (enuRooms eRoomCounter = (enuRooms)0; eRoomCounter < enuRooms._numRooms; eRoomCounter++)
{
if (cNumTurnsToReachRooms[(int)eRoomCounter] == null)
cNumTurnsToReachRooms[(int)eRoomCounter] = new classTurnsReachRoom();
cNumTurnsToReachRooms[(int)eRoomCounter].resetCost();
cNumTurnsToReachRooms[(int)eRoomCounter].eRoom = eRoomCounter;
}
if (eRoom < enuRooms._numRooms)
cNumTurnsToReachRooms[(int)eRoom].setCost(0);
}
public bool ShortestPath()
{
resetShortestPath();
int intStartTurnCost = 0;
enuRooms eCurrentRoom = eRoom;
classSearchElement cSE;
startShortestPath:
if (eCurrentRoom == enuRooms.start) // this suspect is at starting position
{
cSE = getSE();
cSE.set(ptFirstTile, enuDir.secretPassage, 1, intStartTurnCost);
cShortestPath[cSE.pt.X, cSE.pt.Y] = cSE;
enQSE(ref cSE);
}
else if (eCurrentRoom == enuRooms.tiles) // this suspect is on a floor tile outside a room
{
cSE = getSE();
cSE.set(ptTile, enuDir.secretPassage, 0, intStartTurnCost);
cShortestPath[cSE.pt.X, cSE.pt.Y] = cSE;
enQSE(ref cSE);
}
else
{ // this suspect is in a room
classRoom cRoom = MainForm.cRooms[(int)eCurrentRoom];
Point[] ptDoors = cRoom.getValidDoors();
for (int intDoorCounter = 0; intDoorCounter < ptDoors.Length; intDoorCounter++)
{
if (classSuspect.cFloor[ptDoors[intDoorCounter].X, ptDoors[intDoorCounter].Y].dirDoor == enuDir.secretPassage)
{
intStartTurnCost = 0;
switch (eCurrentRoom)
{
case enuRooms.Study:
ptDoors[intDoorCounter] = new Point(0, 0);
break;
case enuRooms.Lounge:
ptDoors[intDoorCounter] = new Point(23, 0);
break;
case enuRooms.Kitchen:
ptDoors[intDoorCounter] = new Point(23, 23);
break;
case enuRooms.Conservatory:
ptDoors[intDoorCounter] = new Point(0, 23);
break;
}
}
else
intStartTurnCost = 0;
cSE = getSE();
cSE.set(ptDoors[intDoorCounter], enuDir.secretPassage, 0, intStartTurnCost);
cShortestPath[cSE.pt.X, cSE.pt.Y] = cSE;
enQSE(ref cSE);
}
}
cSE = deQSE();
int intAverageRoll = 3;
while (cSE != null)
{
classFloor cTile = cFloor[cSE.pt.X, cSE.pt.Y];
if (cTile.eType == enuFloor.door && cTile.dirDoor == enuDir.secretPassage && cTile.eRoom != eRoom)
{ // take secret passage
if (cNumTurnsToReachRooms[(int)cFloor[cSE.pt.X, cSE.pt.Y].eRoom].setCost((cSE.intTurns + 1) * 3))
{
classRoom cRoom = MainForm.cRooms[(int)cFloor[cSE.pt.X, cSE.pt.Y].eRoom];
for (int intDoorCounter = 0; intDoorCounter < cRoom.ptDoors.Length; intDoorCounter++)
{
if (cShortestPath[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y] == null
&& cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor != enuDir.secretPassage)
{
classSearchElement cSENew = getSE();
cSENew.set(cRoom.ptDoors[intDoorCounter], cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor, 0, cSE.intTurns + 1);
cShortestPath[cSENew.pt.X, cSENew.pt.Y] = cSENew;
enQSE(ref cSENew);
}
}
}
}
else
for (enuDir dirCounter = enuDir.north; dirCounter <= enuDir.west; dirCounter++)
{
bool bolDoor = (cTile.eType == enuFloor.door);
if ((bolDoor && cTile.dirDoor == dirCounter)
|| !bolDoor)
{
Point ptDir = MainForm.movePoint(cSE.pt, dirCounter);
if (ptDir.X < MainForm.sz.Width && ptDir.X >= 0 && ptDir.Y < MainForm.sz.Height && ptDir.Y >= 0)
{
classFloor cNewTile = cFloor[ptDir.X, ptDir.Y];
if (cNewTile.eType == enuFloor.tile
&& MainForm.floorTileIsFree(ptDir))
{ // floor tile
if (cShortestPath[ptDir.X, ptDir.Y] == null) // this new tile has not yet been seen
{
classSearchElement cSENew = getSE();
int intNewSteps = cSE.intSteps + 1;
int intNewTurns = cSE.intTurns;
if (intNewSteps > intAverageRoll)
{
intNewSteps = 1;
intNewTurns++;
}
cSENew.set(ptDir, MainForm.getOppDir(dirCounter), intNewSteps, intNewTurns);
cShortestPath[cSENew.pt.X, cSENew.pt.Y] = cSENew;
enQSE(ref cSENew);
}
}
else if (cNewTile.eType == enuFloor.door)
{ // door to a room
if (cNewTile.dirDoor == MainForm.getOppDir(dirCounter))
{
if (cNumTurnsToReachRooms[(int)cFloor[ptDir.X, ptDir.Y].eRoom].setCost((cSE.intTurns * 3 + cSE.intSteps + 1)))
{
classSearchElement cSENew = getSE();
int intNewSteps = cSE.intSteps + 1;
int intNewTurns = cSE.intTurns;
if (intNewSteps > intAverageRoll)
{
intNewSteps = 1;
intNewTurns++;
}
cSENew.set(ptDir, MainForm.getOppDir(dirCounter), intNewSteps, intNewTurns);
cShortestPath[cSENew.pt.X, cSENew.pt.Y] = cSENew;
classRoom cRoom = MainForm.cRooms[(int)cFloor[cSENew.pt.X, cSENew.pt.Y].eRoom];
for (int intDoorCounter = 0; intDoorCounter < cRoom.ptDoors.Length; intDoorCounter++)
{
if (cShortestPath[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y] == null
&& cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor != enuDir.secretPassage)
{
cSENew = getSE();
cSENew.set(cRoom.ptDoors[intDoorCounter], cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor, 0, intNewTurns + 1);
cShortestPath[cSENew.pt.X, cSENew.pt.Y] = cSENew;
enQSE(ref cSENew);
}
else if (cShortestPath[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y] == null
&& cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor == enuDir.secretPassage)
{
cSENew = getSE();
switch (cRoom.name)
{
case enuRooms.Study:
cSENew.set(new Point(0, 0), enuDir.secretPassage, 0, intNewTurns);
break;
case enuRooms.Lounge:
cSENew.set(new Point(23, 0), enuDir.secretPassage, 0, intNewTurns);
break;
case enuRooms.Kitchen:
cSENew.set(new Point(23, 23), enuDir.secretPassage, 0, intNewTurns);
break;
case enuRooms.Conservatory:
cSENew.set(new Point(0, 23), enuDir.secretPassage, 0, intNewTurns);
break;
}
cShortestPath[cSENew.pt.X, cSENew.pt.Y] = cSENew;
enQSE(ref cSENew);
}
}
}
}
}
}
}
}
cSE = deQSE();
}
// debugging test
bool bolRetVal = true;
for (int intX = 0; intX < MainForm.sz.Width; intX++)
for (int intY = 0; intY < MainForm.sz.Height; intY++)
if (cShortestPath[intX, intY] != null)
{
bolRetVal = false;
if (cShortestPath[intX, intY].pt.X != intX || cShortestPath[intX, intY].pt.Y != intY)
MessageBox.Show("setAllowableMoves() error : cell misplaced (" + intX.ToString() + "," + intY.ToString() + ") thinks it belongs to (" + cShortestPath[intX, intY].pt.X.ToString() + "," + cShortestPath[intX, intY].pt.Y.ToString() + ")");
}
//goto startAgain;
return bolRetVal;
}
public void removeSuspectFromDoorways()
{
if (eRoom == enuRooms.tiles)
{
if (cFloor[ptTile.X, ptTile.Y].eType == enuFloor.tile)
{
for (enuDir eDirCounter = (enuDir)0; eDirCounter < enuDir.secretPassage; eDirCounter++)
{
Point ptNext = MainForm.movePoint(ptTile, eDirCounter);
if (cFloor[ptNext.X, ptNext.Y].eType == enuFloor.door)
{
eRoom = cFloor[ptNext.X, ptNext.Y].eRoom;
return;
}
}
}
}
}
public bool setAllowableMoves()
{
startAgain:
resetAllowableMoves();
classSearchElement cSE;
if (eRoom == enuRooms.start) // this suspect is at starting position
{
cSE = getSE();
cSE.set(ptFirstTile, 1, enuDir.secretPassage);
cSEAllowableMoves[cSE.pt.X, cSE.pt.Y] = cSE;
enQSE(ref cSE);
}
else if (eRoom == enuRooms.tiles) // this suspect is on a floor tile outside a room
{
cSE = getSE();
cSE.set(ptTile, 0, enuDir.secretPassage);
cSEAllowableMoves[cSE.pt.X, cSE.pt.Y] = cSE;
enQSE(ref cSE);
}
else
{ // this suspect is in a room
classRoom cRoom = MainForm.cRooms[(int)eRoom];
for (int intDoorCounter = 0; intDoorCounter < cRoom.ptDoors.Length; intDoorCounter++)
{
cSE = getSE();
cSE.set(cRoom.ptDoors[intDoorCounter], 0, enuDir.secretPassage);
if (cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor == enuDir.secretPassage)
enQSE(ref cSE);
else
{
cSE.set(cRoom.ptDoors[intDoorCounter], 0, enuDir.secretPassage);
cSEAllowableMoves[cSE.pt.X, cSE.pt.Y] = cSE;
enuDir dirDoor = cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor;
Point ptTileOutsideDoor = MainForm.movePoint(cRoom.ptDoors[intDoorCounter], dirDoor);
cSE.set(ptTileOutsideDoor, 0,MainForm.getOppDir( dirDoor));
cSEAllowableMoves[cSE.pt.X, cSE.pt.Y] = cSE;
enQSE(ref cSE);
}
}
}
cSE = deQSE();
while (cSE != null)
{
if (cSE.intSteps < MainForm.udrRollDieInfo.intDieValue)
{
classFloor cTile = cFloor[cSE.pt.X, cSE.pt.Y];
for (enuDir dirCounter = enuDir.north; dirCounter <= enuDir.west; dirCounter++)
{
bool bolDoor = (cTile.eType == enuFloor.door);
if ((bolDoor && cTile.dirDoor == dirCounter)
|| !bolDoor)
{
Point ptDir = MainForm.movePoint(cSE.pt, dirCounter);
if (ptDir.X < MainForm.sz.Width && ptDir.X >= 0 && ptDir.Y < MainForm.sz.Height && ptDir.Y >= 0)
{
classFloor cNewTile = cFloor[ptDir.X, ptDir.Y];
if (cNewTile.eType == enuFloor.tile
&& MainForm.floorTileIsFree(ptDir))
{ // floor tile
if (cSEAllowableMoves[ptDir.X, ptDir.Y] == null) // this new tile has not yet been seen
{
classSearchElement cSENew = getSE();
cSENew.set(ptDir, cSE.intSteps + 1, MainForm.getOppDir(dirCounter));
cSEAllowableMoves[cSENew.pt.X, cSENew.pt.Y] = cSENew;
enQSE(ref cSENew);
}
}
else if (cNewTile.eType == enuFloor.door)
{ // door to a room
if (cNewTile.dirDoor == MainForm.getOppDir(dirCounter))
{
classSearchElement cSENew = getSE();
cSENew.set(ptDir, cSE.intSteps + 1, MainForm.getOppDir(dirCounter));
cSEAllowableMoves[cSENew.pt.X, cSENew.pt.Y] = cSENew;
}
}
}
}
}
}
else if (cSE.intSteps == MainForm.udrRollDieInfo.intDieValue)
{
// if next to a door -> allow enter room
classFloor cTile = cFloor[cSE.pt.X, cSE.pt.Y];
for (enuDir dirCounter = enuDir.north; dirCounter <= enuDir.west; dirCounter++)
{
Point ptDir = MainForm.movePoint(cSE.pt, dirCounter);
if (ptDir.X < MainForm.sz.Width && ptDir.X >= 0 && ptDir.Y < MainForm.sz.Height && ptDir.Y >= 0)
{
classFloor cNewTile = cFloor[ptDir.X, ptDir.Y];
if (cNewTile.eType == enuFloor.door)
{ // door to a room
if (cNewTile.dirDoor == MainForm.getOppDir(dirCounter))
{
classSearchElement cSENew = getSE();
cSENew.set(ptDir, cSE.intSteps + 1, MainForm.getOppDir(dirCounter));
cSEAllowableMoves[cSENew.pt.X, cSENew.pt.Y] = cSENew;
}
}
}
}
}
cSE = deQSE();
}
if (eRoom < enuRooms._numRooms) // this suspect is inside a room -> remove doors from allowable moves
removeDoorsFromAllowableMoves();
bool bolRetVal = true;
for (int intX = 0; intX < MainForm.sz.Width; intX++)
for (int intY = 0; intY < MainForm.sz.Height; intY++)
if (cSEAllowableMoves[intX, intY] != null)
{
bolRetVal = false;
if (cSEAllowableMoves[intX, intY].pt.X != intX || cSEAllowableMoves[intX, intY].pt.Y != intY)
MessageBox.Show("setAllowableMoves() error : cell misplaced (" + intX.ToString() + "," + intY.ToString() + ") thinks it belongs to (" + cSEAllowableMoves[intX, intY].pt.X.ToString() + "," + cSEAllowableMoves[intX, intY].pt.Y.ToString() + ")");
}
//goto startAgain;
return bolRetVal;
}
void removeDoorsFromAllowableMoves()
{ // this is called when the suspect is moving away from a room
for (int intX = 0; intX < MainForm.sz.Width; intX++)
for (int intY = 0; intY < MainForm.sz.Height; intY++)
{
if (cSEAllowableMoves[intX, intY] != null)
{
classFloor cTile = cFloor[intX, intY];
if ((cTile.eType == enuFloor.door && cTile.eRoom == oppositeCornerRoomID(eRoom))
|| (cTile.eType == enuFloor.door && cTile.eRoom == eRoom))
{
disposeSE(ref cSEAllowableMoves[intX, intY]);
cSEAllowableMoves[intX, intY] = null;
}
}
}
}
enuRooms oppositeCornerRoomID(enuRooms eRoom)
{
switch (eRoom)
{
case enuRooms.Study:
return enuRooms.Kitchen;
case enuRooms.Lounge:
return enuRooms.Conservatory;
case enuRooms.Kitchen:
return enuRooms.Study;
case enuRooms.Conservatory:
return enuRooms.Lounge;
default:
return enuRooms._numRooms;
}
}
void enQSE(ref classSearchElement cThisSE)
{
if (searchQ.head == null)
{
searchQ.head = cThisSE;
searchQ.tail = cThisSE;
}
else if (searchQ.tail == searchQ.head)
{
searchQ.head.next = cThisSE;
searchQ.tail = cThisSE;
}
else
{
searchQ.tail.next = cThisSE;
searchQ.tail = cThisSE;
}
}
classSearchElement deQSE()
{
classSearchElement SERetVal = searchQ.head;
if (searchQ.head == null)
{
return null;
}
else if (searchQ.head == searchQ.tail)
{
searchQ.head = searchQ.tail = null;
}
else
{
searchQ.head = searchQ.head.next;
}
return SERetVal;
}
public void receiveCard(ref classCard thisCard)
{
Array.Resize<classCard>(ref cCards, cCards.Length + 1);
cCards[cCards.Length - 1] = thisCard;
checkNote(thisCard.eCardName, eName);
}
public void XNote(enuCards eCard, enuSuspects eSuspect)
{
udrAILogic.eNotes[(int)eSuspect, (int)eCard] = enuNote.X;
bool bolAllXs = true;
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
if (udrAILogic.eNotes[(int)eSuspectCounter, (int)eCard] != enuNote.X)
bolAllXs = false;
}
if (bolAllXs)
{
// we have eliminated all possibilities -> this card is part of the solution
if (MainForm.cCards[(int)eCard].IsARoom)
{
udrAILogic.eRoomsLeft = new enuRooms[1];
udrAILogic.eRoomsLeft[0] = MainForm.getERoomFromCard(eCard);
}
else if (MainForm.cCards[(int)eCard].IsAWeapon)
{
udrAILogic.eWeaponsLeft = new enuWeapons[1];
udrAILogic.eWeaponsLeft[0] = MainForm.getEWeaponFromCard(eCard);
}
else if (MainForm.cCards[(int)eCard].IsASuspect)
{
udrAILogic.eSuspectsLeft = new enuSuspects[1];
udrAILogic.eSuspectsLeft[0] = MainForm.getESuspectFromCard(eCard);
}
else
MessageBox.Show("we have a problem! : xNote(" + eCard.ToString() + ", " + eSuspect.ToString() + ") -> card type invalid");
}
}
/// <summary>
/// called when a suspect has been determined to have a card
/// </summary>
/// <param name="eCard">card which the suspect holds</param>
/// <param name="eSuspect">suspect holding the card</param>
void checkNote(enuCards eCard, enuSuspects eSuspect)
{
// debug start -> test faulty logic
if (eCard == classCard.getECardFromERoom(MainForm.udrMurder.eRoom)
|| eCard == classCard.getECardFromEWeapon(MainForm.udrMurder.eWeapon)
|| eCard == classCard.getECardFromESuspect(MainForm.udrMurder.eSuspect))
{
MessageBox.Show("checkNote : faulty logic");
return;
}
// debug end
udrAILogic.eNotes[(int)eSuspect, (int)eCard] = enuNote.check;
if ((eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 400 == 0) // ai may notice that all of this suspect's cards have been identified
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 10 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0)
|| (eAILevel == enuAILevel.genius ))
{
int intCountNumCardsKnown = 0;
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
{
if (udrAILogic.eNotes[(int)eSuspect, (int)eCardCounter] == enuNote.check)
intCountNumCardsKnown++;
}
if (intCountNumCardsKnown == MainForm.cSuspects[(int)eSuspect].cCards.Length)
{
// all of this suspect's cards have been identified -> X the ones that are unknown for this suspect
for (enuCards eCardCounter = (enuCards)0; eCardCounter < enuCards._numCards; eCardCounter++)
{
if (udrAILogic.eNotes[(int)eSuspect, (int)eCardCounter] != enuNote.check)
XNote(eCardCounter, eSuspect);
}
}
}
// for this card : set 'X' in note for all suspects (they DO NOT have this card) and a 'check' for suspect who does have it
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{
if (eSuspect != eSuspectCounter)
{
if (udrAILogic.eNotes[(int)eSuspectCounter, (int)eCard] != enuNote.X)
{
XNote(eCard, eSuspectCounter);
startSetLoop:
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled != null)
for (int intSetCounter = 0; intSetCounter < udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled.Length; intSetCounter++)
{
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter] != null)
{
for (int intCardCounter = 0; intCardCounter < udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length; intCardCounter++)
{
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[intCardCounter] == eCard)
{ // since we now know that this suspect does NOT have this card
// this suspect therefore did NOT show this card previously
// remove this card from set of unknowns
udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[intCardCounter] = udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length - 1];
Array.Resize<enuCards>(ref udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown, udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length - 1);
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length == 1)
{ // there is only one card remaining -> the card remaining MUST BE the one this suspect showed (has)
checkNote(udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[0], eSuspectCounter);
}
goto startSetLoop;
}
}
}
}
}
}
}
// scan through all AI sets
// if this new 'known' card is among the list of unknown sets -> cancel those sets
startScanningPreviousUnknownSets:
if (udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled != null)
{ // scan each of this suspects MayHaveBeenShown sets of cards
for (int intSetCounter = 0; intSetCounter < udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled.Length; intSetCounter++)
{ // scan each card in this set
for (int intCardCounter = 0; intCardCounter < udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length; intCardCounter++)
{ // compare each card in this set to new 'known' card eCard
if (udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[intCardCounter] == eCard)
{
// this set needs to be deleted
udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled[intSetCounter] = udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled[udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled.Length - 1];
Array.Resize<classCardsCalled>(ref udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled, udrAILogic.cSuspectsUnknowns[(int)eSuspect].cSetsOfCardsCalled.Length - 1);
goto startScanningPreviousUnknownSets;
}
}
}
}
int intNumSuspects = (int)enuSuspects._numSuspects;
int intNumWeapons = (int)enuWeapons._numWeapons;
if ((int)eCard < intNumSuspects)
{ // known card is a suspect
enuSuspects eSuspectCardShown = (enuSuspects)((int)eCard);
for (int intUnknownSuspectsCounter = 0; intUnknownSuspectsCounter < udrAILogic.eSuspectsLeft.Length; intUnknownSuspectsCounter++)
{
if (udrAILogic.eSuspectsLeft[intUnknownSuspectsCounter] == eSuspectCardShown)
{
udrAILogic.eSuspectsLeft[intUnknownSuspectsCounter] = udrAILogic.eSuspectsLeft[udrAILogic.eSuspectsLeft.Length - 1];
Array.Resize<enuSuspects>(ref udrAILogic.eSuspectsLeft, udrAILogic.eSuspectsLeft.Length - 1);
}
}
}
else if ((int)eCard < intNumSuspects + intNumWeapons)
{ // known card is a weapon
enuWeapons eWeaponCardShown = (enuWeapons)((int)eCard - intNumSuspects);
for (int intUnknownWeaponsCounter = 0; intUnknownWeaponsCounter < udrAILogic.eWeaponsLeft.Length; intUnknownWeaponsCounter++)
{
if (udrAILogic.eWeaponsLeft[intUnknownWeaponsCounter] == eWeaponCardShown)
{
udrAILogic.eWeaponsLeft[intUnknownWeaponsCounter] = udrAILogic.eWeaponsLeft[udrAILogic.eWeaponsLeft.Length - 1];
Array.Resize<enuWeapons>(ref udrAILogic.eWeaponsLeft, udrAILogic.eWeaponsLeft.Length - 1);
}
}
}
else
{ // known card is a room
enuRooms eRoomCardShown = (enuRooms)((int)eCard - intNumSuspects - intNumWeapons);
for (int intUnknownRoomsCounter = 0; intUnknownRoomsCounter < udrAILogic.eRoomsLeft.Length; intUnknownRoomsCounter++)
{
if (udrAILogic.eRoomsLeft[intUnknownRoomsCounter] == eRoomCardShown)
{
udrAILogic.eRoomsLeft[intUnknownRoomsCounter] = udrAILogic.eRoomsLeft[udrAILogic.eRoomsLeft.Length - 1];
Array.Resize<enuRooms>(ref udrAILogic.eRoomsLeft, udrAILogic.eRoomsLeft.Length - 1);
}
}
}
}
bool IHaveThisCard(enuRooms eRoom) { return IHaveThisCard(classCard.getECardFromERoom(eRoom)); }
bool IHaveThisCard(enuWeapons eWeapon) { return IHaveThisCard(classCard.getECardFromEWeapon(eWeapon)); }
bool IHaveThisCard(enuSuspects eSuspect) { return IHaveThisCard(classCard.getECardFromESuspect(eSuspect)); }
bool IHaveThisCard(enuCards eCard)
{
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
if (cCards[intCardCounter].eCardName == eCard)
return true;
return false;
}
public enuCards RespondToSuggestion()
{
enuCards[] eSuggestedCardsIHave = new enuCards[0];
if (IHaveThisCard(MainForm.udrSuggestion.eSuspect))
appendECardArray(ref eSuggestedCardsIHave, classCard.getECardFromESuspect(MainForm.udrSuggestion.eSuspect));
if (IHaveThisCard(MainForm.udrSuggestion.eWeapon))
appendECardArray(ref eSuggestedCardsIHave, classCard.getECardFromEWeapon(MainForm.udrSuggestion.eWeapon));
if (IHaveThisCard(MainForm.udrSuggestion.eRoom))
appendECardArray(ref eSuggestedCardsIHave, classCard.getECardFromERoom(MainForm.udrSuggestion.eRoom));
if (eSuggestedCardsIHave.Length > 1)
{
// cycle through the cards I can respond and see if I've already shown one of them to the suggesting suspect
for (int intCardCounter = 0; intCardCounter < eSuggestedCardsIHave.Length; intCardCounter++)
{
if (udrAILogic.eNotes[MainForm.intSuspectTurn, (int)eSuggestedCardsIHave[intCardCounter]] == enuNote.shown)
return eSuggestedCardsIHave[intCardCounter];
}
// if none of the valid cards have already been shown -> show a new one
int intRnd = (int)(MainForm.rnd.NextDouble() * 1000) % eSuggestedCardsIHave.Length;
udrAILogic.eNotes[MainForm.intSuspectTurn, (int)eSuggestedCardsIHave[intRnd]] = enuNote.shown;
return eSuggestedCardsIHave[intRnd];
}
else if (eSuggestedCardsIHave.Length == 1)
{
return eSuggestedCardsIHave[0];
}
return enuCards.NoCardShown;
}
void appendECardArray(ref enuCards[] eCardArray, enuCards eNewCard)
{
Array.Resize<enuCards>(ref eCardArray, eCardArray.Length + 1);
eCardArray[eCardArray.Length - 1] = eNewCard;
}
public void ResponseToSuggestion(enuSuspects eSuspectResponding, enuCards eCardShown)
{
enuCards[] eCardsCalled = new enuCards[3];
eCardsCalled[0] = MainForm.getCardFromERoom(MainForm.udrSuggestion.eRoom);
eCardsCalled[1] = MainForm.getCardFromESuspect(MainForm.udrSuggestion.eSuspect);
eCardsCalled[2] = MainForm.getCardFromEWeapon(MainForm.udrSuggestion.eWeapon);
// scan list of cards which we know the responding suspect does NOT have and eliminate those from the current suggestion
beginScanCardsCalled:
for (int intCalledCardsCounter = 0; intCalledCardsCounter < eCardsCalled.Length; intCalledCardsCounter++)
{
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
{ // we know the responding suspect has this card -> remove it from the list of currently suggested cards
if ((eSuspectCounter == eSuspectResponding && udrAILogic.eNotes[(int)eSuspectCounter, (int)eCardsCalled[intCalledCardsCounter]] == enuNote.X)
|| (eSuspectCounter != eSuspectResponding && udrAILogic.eNotes[(int)eSuspectCounter, (int)eCardsCalled[intCalledCardsCounter]] == enuNote.check))
{ // we know some responding suspect does NOT HAVE THIS CARD
eCardsCalled[intCalledCardsCounter] = eCardsCalled[eCardsCalled.Length - 1];
Array.Resize<enuCards>(ref eCardsCalled, eCardsCalled.Length - 1);
goto beginScanCardsCalled;
}
else if (eSuspectCounter == eSuspectResponding && udrAILogic.eNotes[(int)eSuspectCounter, (int)eCardsCalled[intCalledCardsCounter]] == enuNote.check)
{
// we already know that the responding suspect has one of the cards -> no inference can be made
return;
}
}
}
if (eCardsCalled.Length == 1 && eCardShown != enuCards.NoCardShown)
{ // after eliminating all known cards we are left with one card and that must be the card which was shown
eCardShown = eCardsCalled[0];
}
if (eCardShown == enuCards.Unknown)
{ // the suspect responding to suggestion holds one of called card but we don't know which of the three (room, suspect or weapon)
// create a new set and append the current list of unknown sets for the responding suspect
if (eAILevel == enuAILevel.genius
|| (eAILevel == enuAILevel.bright && ((int)(MainForm.rnd.NextDouble() * 1000)) % 4 == 0)
|| (eAILevel == enuAILevel.average && ((int)(MainForm.rnd.NextDouble() * 1000)) % 8 == 0)
|| (eAILevel == enuAILevel.dull && ((int)(MainForm.rnd.NextDouble() * 1000)) % 12 == 0)
|| (eAILevel == enuAILevel.stupid && ((int)(MainForm.rnd.NextDouble() * 1000)) % 15 == 0))
{
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled == null)
udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled = new classCardsCalled[0];
Array.Resize<classCardsCalled>(ref udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled, udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled.Length + 1);
udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled.Length - 1] = new classCardsCalled();
udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled.Length - 1].cCardsThatMightHaveBeenShown = eCardsCalled;
}
}
else if (eCardShown == enuCards.NoCardShown)
{ // this Suspect has none of the suggested cards in his hand
// set the responding suspect's notes to reflect that he does not have the called cards
if (eAILevel == enuAILevel.genius
|| (eAILevel == enuAILevel.bright && ((int)(MainForm.rnd.NextDouble() * 1000)) % 2 == 0)
|| (eAILevel == enuAILevel.average && ((int)(MainForm.rnd.NextDouble() * 1000)) % 4 == 0)
|| (eAILevel == enuAILevel.dull && ((int)(MainForm.rnd.NextDouble() * 1000)) % 6 == 0)
|| (eAILevel == enuAILevel.stupid && ((int)(MainForm.rnd.NextDouble() * 1000)) % 8 == 0))
{
for (int intCalledCardCounter = 0; intCalledCardCounter < eCardsCalled.Length; intCalledCardCounter++)
{
XNote(eCardsCalled[intCalledCardCounter], eSuspectResponding);
}
// scan all previous sets of cards for which this suspect has shown one of the called card (above: eCardShown == enuCards.Unknown)
// if any of the suggested cards are included in these sets of unknowns -> we now know that that card was NOT SHOWN because the suspect does not have that card
// eliminate it from the three for that(those) set(s) -> when set is reduced to 1 card -> remaining card is the card he showed, the card he has
// scan each previous set
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled != null)
{
startSetCounterLoop:
for (int intSetCounter = 0; intSetCounter < udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled.Length; intSetCounter++)
{
// scan each card in this previous set
for (int intCardsMayHaveBeenShownCounter = 0; intCardsMayHaveBeenShownCounter < udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length; intCardsMayHaveBeenShownCounter++)
{
// compare to each of the three cards in the current set (current suggestion)
for (int intCardsCalledCounter = 0; intCardsCalledCounter < eCardsCalled.Length; intCardsCalledCounter++)
{
if (eCardsCalled[intCardsCalledCounter] == udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[intCardsMayHaveBeenShownCounter])
{ // we now know that this is NOT the card which the responding suspect showed previously
// remove this card from the list of possible cards which the responding suspect showed in an earlier response to another suggestion
udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[intCardsMayHaveBeenShownCounter] = udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length - 1];
Array.Resize<enuCards>(ref udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown, udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length - 1);
if (udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown.Length == 1)
{ // the only card remaining MUST be the card which this responding suspect showed earlier
checkNote(udrAILogic.cSuspectsUnknowns[(int)eSuspectResponding].cSetsOfCardsCalled[intSetCounter].cCardsThatMightHaveBeenShown[0], eSuspectResponding);
// this set is removed inside checkNote() -> NO NEED TO REMOVE IT HERE
}
goto startSetCounterLoop;
}
}
}
}
}
}
}
else
{
// responding suspect has shown a card
// include this information in our notes
checkNote(eCardShown, eSuspectResponding);
}
}
void setFirstTiles()
{
switch (eName)
{
case enuSuspects.ColMustard:
ptFirstTile = new Point(22, 7);
break;
case enuSuspects.MissScarlet:
ptFirstTile = new Point(16, 1);
break;
case enuSuspects.RevGreen:
ptFirstTile = new Point(9, 23);
break;
case enuSuspects.MrsPeacock:
ptFirstTile = new Point(1, 18);
break;
case enuSuspects.MrsWhite:
ptFirstTile = new Point(14, 23);
break;
case enuSuspects.ProfPlum:
ptFirstTile = new Point(1, 5);
break;
}
}
bool IsACornerRoom() { return IsACornerRoom(eRoom); }
bool IsACornerRoom(enuRooms eThisRoom)
{
return (eThisRoom == enuRooms.Study || eThisRoom == enuRooms.Lounge || eThisRoom == enuRooms.Kitchen || eThisRoom == enuRooms.Conservatory);
}
bool useSecretPassage()
{
if (!IsACornerRoom())
return false;
enuRooms eOppositeCornerRoom = MainForm.cRooms[(int)eRoom].oppositeCornerRoom();
// if heading to opposite corner room
if (udrAILogic.eDestinationRoom == eOppositeCornerRoom)
{
switch (eRoom)
{
case enuRooms.Study:
udrAILogic.ptDestinationTile = new Point(0, 0);
return true;
case enuRooms.Lounge:
udrAILogic.ptDestinationTile = new Point(23, 0);
return true;
case enuRooms.Kitchen:
udrAILogic.ptDestinationTile = new Point(23, 23);
return true;
case enuRooms.Conservatory:
udrAILogic.ptDestinationTile = new Point(0, 23);
return true;
}
}
// trace steps back from target room
enuRooms eCurrentRoom = udrAILogic.eDestinationRoom;
while (true)
{
// in a room
Point ptBestDoorFromRoom = new Point(0, 0);
if (getBestDoorOutThisRoom(eCurrentRoom, ref ptBestDoorFromRoom, true))
{
bool bolOnTiles = true;
if (ptBestDoorFromRoom.X < 0)
{ // use a secret passage
if (Math.Abs(ptBestDoorFromRoom.X) % (int)enuRooms._numRooms == (int)eRoom)
return true;
else
{
eCurrentRoom = (enuRooms)((int)Math.Abs(ptBestDoorFromRoom.X) % (int)enuRooms._numRooms);
bolOnTiles = false;
}
}
else
{
Point ptTile = MainForm.movePoint(ptBestDoorFromRoom, cFloor[ptBestDoorFromRoom.X, ptBestDoorFromRoom.Y].dirDoor);
while (bolOnTiles)
{
ptTile = MainForm.movePoint(ptTile, cShortestPath[ptTile.X, ptTile.Y].SrcDir);
bolOnTiles = (cFloor[ptTile.X, ptTile.Y].eType == enuFloor.tile);
}
eCurrentRoom = cFloor[ptTile.X, ptTile.Y].eRoom;
}
if (eCurrentRoom == eRoom)
return false;
}
else
{
return false;
}
}
//classRoom cOppRoom = MainForm.cRooms[(int)eOppositeCornerRoom];
//Point[] ptOppositeCornerRoomValidDoors = cOppRoom.getValidDoors();
//for (int intOppCorRooValDoorCounter = 0; intOppCorRooValDoorCounter < ptOppositeCornerRoomValidDoors.Length; intOppCorRooValDoorCounter++)
//{
// if (classSuspect.cFloor[ptOppositeCornerRoomValidDoors[intOppCorRooValDoorCounter].X, ptOppositeCornerRoomValidDoors[intOppCorRooValDoorCounter].Y].dirDoor != enuDir.secretPassage)
// {
// Point ptTileOutsideOppRoomDoor = MainForm.movePoint(ptOppositeCornerRoomValidDoors[intOppCorRooValDoorCounter], classSuspect.cFloor[ptOppositeCornerRoomValidDoors[intOppCorRooValDoorCounter].X, ptOppositeCornerRoomValidDoors[intOppCorRooValDoorCounter].Y].dirDoor);
// if (cShortestPath[ptTileOutsideOppRoomDoor.X, ptTileOutsideOppRoomDoor.Y].intCost == 4)
// return true;
// }
//}
return false;
}
bool eRoomIsLeft(enuRooms eThisRoom)
{
for (int intRoomsLeftCounter = 0; intRoomsLeftCounter < udrAILogic.eRoomsLeft.Length; intRoomsLeftCounter++)
if (udrAILogic.eRoomsLeft[intRoomsLeftCounter] == eThisRoom)
return true;
return false;
}
bool IWantToAccuse()
{
return (udrAILogic.eRoomsLeft.Length == 1 && udrAILogic.eSuspectsLeft.Length == 1 && udrAILogic.eWeaponsLeft.Length == 1);
}
public void playTurn()
{
ShortestPath();
if (bolMustMove)
PickDestinationRoom();
else
udrAILogic.eDestinationRoom = eRoom;
/* /// debug start
udrAILogic.eRoomsLeft = new enuRooms[1];
udrAILogic.eRoomsLeft[0] = MainForm.udrMurder.eRoom;
udrAILogic.eWeaponsLeft = new enuWeapons[1];
udrAILogic.eWeaponsLeft[0] = MainForm.udrMurder.eWeapon;
udrAILogic.eSuspectsLeft = new enuSuspects[1];
udrAILogic.eSuspectsLeft[0] = MainForm.udrMurder.eSuspect;
/// debug end */
if (IWantToAccuse())
{
udtMurder udrAccusation = new udtMurder();
udrAccusation.eRoom = udrAILogic.eRoomsLeft[0];
udrAccusation.eSuspect = udrAILogic.eSuspectsLeft[0];
udrAccusation.eWeapon = udrAILogic.eWeaponsLeft[0];
MainForm.Accuse(eName, udrAccusation);
return;
}
if (!bolCanSuggest && udrAILogic.eDestinationRoom == eRoom)
{ // the room I am in is the destination room because there is no way out
// I can NOT suggest -> end turn
MainForm.eMode = enuMode.endTurn;
resetShortestPath();
return;
}
if (bolCanSuggest && eRoomIsLeft(eRoom)
&& !(eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 5000 == 0) // lower ai may make a mistake and neglect to suggest
&& !(eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 1000 == 0)
&& !(eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0)
&& !(eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 100 == 0)
&& !(eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 10 == 0))
{
makeSuggestion();
return;
}
else
{
if (useSecretPassage())
{
switch (eRoom)
{
case enuRooms.Study:
udrAILogic.ptDestinationTile = new Point(0, 0);
break;
case enuRooms.Lounge:
udrAILogic.ptDestinationTile = new Point(23, 0);
break;
case enuRooms.Kitchen:
udrAILogic.ptDestinationTile = new Point(23, 23);
break;
case enuRooms.Conservatory:
udrAILogic.ptDestinationTile = new Point(0, 23);
break;
}
allowSecretPassage();
}
else
{
MainForm.rollDie();
return;
}
MainForm.picMouseClick((object)MainForm.picBoard, new MouseEventArgs(MouseButtons.Left, 1, MainForm.ptBoardTL.X + 28 * udrAILogic.ptDestinationTile.X + 3, MainForm.ptBoardTL.Y + 28 * udrAILogic.ptDestinationTile.Y + 3, 0));
bolMustMove = false;
if (bolCanSuggest)
makeSuggestion();
return;
}
endPlayTurn:
bolCanSuggest = false;
resetShortestPath();
}
public void endShowAllowableMoves()
{
if (!PickDestinationTile())
{ // can't move
bolCanSuggest = false;
resetShortestPath();
}
bolMustMove = false;
MainForm.picMouseClick((object)MainForm.picBoard, new MouseEventArgs(MouseButtons.Left, 1, MainForm.ptBoardTL.X + 28 * udrAILogic.ptDestinationTile.X + 3, MainForm.ptBoardTL.Y + 28 * udrAILogic.ptDestinationTile.Y + 3, 0));
if (bolCanSuggest)
makeSuggestion();
}
public void playTurnAfterMove()
{
if (bolCanSuggest)
{
makeSuggestion();
return;
}
bolCanSuggest = false;
resetShortestPath();
MainForm.eMode = enuMode.endTurn;
}
void prepareSuggestionAI()
{
udrAILogic.udrSuggestionAI.udrRoomCardsMysteryFrequency = new udtSuggestionAI_frequenCards[0];
udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency = new udtSuggestionAI_frequenCards[0];
udrAILogic.udrSuggestionAI.udrSuspectMysteryFrequency = new udtSuggestionAI_frequenCards[0];
for (int intSuspectCounter = 0; intSuspectCounter < udrAILogic.udrSuggestionAI.suspectMysteryInfo.Length; intSuspectCounter++)
{
// scan each suspect's unknown "mystery" card sets
// count the number of each type of card and order them into that suspect's arrays AND accumulate into overall array
udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrRoomsMystery = new udtSuggestionAI_frequenCards[0];
udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrWeaponCardsMystery = new udtSuggestionAI_frequenCards[0];
udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrSuspectCardsMystery = new udtSuggestionAI_frequenCards[0];
classCardsCalled[] cCardSets = udrAILogic.cSuspectsUnknowns[(int)udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].eSuspect].cSetsOfCardsCalled;
if (cCardSets != null)
{
for (int intSetCounter = 0; intSetCounter < cCardSets.Length; intSetCounter++)
{
enuCards[] eCardsCalled = cCardSets[intSetCounter].cCardsThatMightHaveBeenShown;
// for each card which this suspect was asked when he showed a card
// separate into type : room, weapon or suspect
for (int intCardCounter = 0; intCardCounter < eCardsCalled.Length; intCardCounter++)
{
if (MainForm.cCards[(int)eCardsCalled[intCardCounter]].IsARoom)
{
addECardToFrequencyCards(ref udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrRoomsMystery, eCardsCalled[intCardCounter]);
addECardToFrequencyCards(ref udrAILogic.udrSuggestionAI.udrRoomCardsMysteryFrequency, eCardsCalled[intCardCounter]);
}
else if (MainForm.cCards[(int)eCardsCalled[intCardCounter]].IsAWeapon)
{
addECardToFrequencyCards(ref udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrWeaponCardsMystery, eCardsCalled[intCardCounter]);
addECardToFrequencyCards(ref udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency, eCardsCalled[intCardCounter]);
}
else if (MainForm.cCards[(int)eCardsCalled[intCardCounter]].IsASuspect)
{
addECardToFrequencyCards(ref udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrSuspectCardsMystery, eCardsCalled[intCardCounter]);
addECardToFrequencyCards(ref udrAILogic.udrSuggestionAI.udrSuspectMysteryFrequency, eCardsCalled[intCardCounter]);
}
else
MessageBox.Show("this should NOT HAPPEN! : prepareSuggestionAI() -> don't know what kind of card this is");
}
}
// reorder the three type arrays according to frequency
reorderFrequencyCardsByNumber(ref udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrRoomsMystery);
reorderFrequencyCardsByNumber(ref udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrSuspectCardsMystery);
reorderFrequencyCardsByNumber(ref udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrWeaponCardsMystery);
}
}
// reorder three overall type arrays according to frequency
reorderFrequencyCardsByNumber(ref udrAILogic.udrSuggestionAI.udrRoomCardsMysteryFrequency);
reorderFrequencyCardsByNumber(ref udrAILogic.udrSuggestionAI.udrSuspectMysteryFrequency);
reorderFrequencyCardsByNumber(ref udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency);
}
void reorderFrequencyCardsByNumber(ref udtSuggestionAI_frequenCards[] udrFreqCards)
{
if (udrFreqCards == null)
return;
int intBestIndex, intInnerLoop, intOuterLoop;
for (intOuterLoop = 0; intOuterLoop < udrFreqCards.Length - 1; intOuterLoop++)
{
intBestIndex = intOuterLoop;
for (intInnerLoop = intOuterLoop + 1; intInnerLoop < udrFreqCards.Length; intInnerLoop++)
{
if (udrFreqCards[intInnerLoop].intNumMystery > udrFreqCards[intBestIndex].intNumMystery)
intBestIndex = intInnerLoop;
}
if (intBestIndex != intOuterLoop)
{
enuCards eCardBestIndex = udrFreqCards[intBestIndex].eCards;
int intNumBestIndex = udrFreqCards[intBestIndex].intNumMystery;
udrFreqCards[intBestIndex].eCards = udrFreqCards[intOuterLoop].eCards;
udrFreqCards[intBestIndex].intNumMystery = udrFreqCards[intOuterLoop].intNumMystery;
udrFreqCards[intOuterLoop].eCards = eCardBestIndex;
udrFreqCards[intOuterLoop].intNumMystery = intNumBestIndex;
}
}
}
void addECardToFrequencyCards(ref udtSuggestionAI_frequenCards[] udrFreqCards, enuCards eNewCard)
{
if (udrFreqCards == null)
udrFreqCards = new udtSuggestionAI_frequenCards[0];
for (int intRoomCounter = 0; intRoomCounter < udrFreqCards.Length; intRoomCounter++)
{
if (udrFreqCards[intRoomCounter].eCards == eNewCard)
{ // this suspect has more than one set which includes this card as a possible solution
udrFreqCards[intRoomCounter].intNumMystery++;
return;
}
}
// we have scanned the list and NOT found this new room
// increase size of array and insert this new room at the end
Array.Resize<udtSuggestionAI_frequenCards>(ref udrFreqCards, udrFreqCards.Length + 1);
udrFreqCards[udrFreqCards.Length - 1] = new udtSuggestionAI_frequenCards();
udrFreqCards[udrFreqCards.Length - 1].eCards = eNewCard;
udrFreqCards[udrFreqCards.Length - 1].intNumMystery = 1;
}
public void makeSuggestion()
{
prepareSuggestionAI();
pickSuspectForSuggestion();
pickWeaponForSuggestion();
MainForm.udrSuggestion.eRoom = eRoom;
MainForm.cLibPicTraySuspects.setSelectedImage((int)MainForm.udrSuggestion.eSuspect);
MainForm.cLibPicTraySuspects.Angle = MainForm.cLibPicTraySuspects.FrontAngle - MainForm.cLibPicTraySuspects.Tray[(int)MainForm.udrSuggestion.eSuspect].angleOnTray;
MainForm.cLibPicTraySuspects.RefreshTrayImage();
MainForm.cLibPicTrayWeapons.setSelectedImage((int)MainForm.udrSuggestion.eWeapon);
MainForm.cLibPicTrayWeapons.Angle = MainForm.cLibPicTrayWeapons.FrontAngle - MainForm.cLibPicTrayWeapons.Tray[(int)MainForm.udrSuggestion.eWeapon].angleOnTray;
MainForm.cLibPicTrayWeapons.RefreshTrayImage();
MainForm.udrSuggestionAnimation.intProveSuggestionCycleCounter = 1;
MainForm.eMode = enuMode.Suggest;
bolCanSuggest = false;
MainForm.btnMakeSuggestion_OK_click();
}
void pickSuspectForSuggestion()
{
if ((eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0) // ai may make a poor random choice from ALL suspects
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 5000 == 0))
{
MainForm.udrSuggestion.eSuspect = (enuSuspects)((int)(MainForm.rnd.NextDouble() * 1000) % (int)enuSuspects._numSuspects);
return;
}
else if (eAILevel == enuAILevel.stupid // ai may make a poor random choice from ALL REMAINING suspects
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0))
{
MainForm.udrSuggestion.eSuspect = udrAILogic.eSuspectsLeft[(int)(MainForm.rnd.NextDouble() * 1000) % udrAILogic.eSuspectsLeft.Length];
return;
}
if (udrAILogic.eSuspectsLeft.Length == 1)
{ // I have narrowed down the number of suspects to one and now know which suspect has committed the murder
// do not reveal this information to other players
// select a suspect whose card I have in my hands
if ((int)(MainForm.rnd.NextDouble() * 1000) % 3 == 0)
{ // one third of the time -> pick the one I know is part of the solution
MainForm.udrSuggestion.eSuspect = udrAILogic.eSuspectsLeft[0];
}
else
{
if (eSuspectsIHoldACardFor.Length > 0)
{
MainForm.udrSuggestion.eSuspect = eSuspectsIHoldACardFor[(int)(MainForm.rnd.NextDouble() * 1000) % eSuspectsIHoldACardFor.Length];
return;
}
// I don't hold any suspect cards
// go around the table in reverse order and pick the first suspect card I know the last suspect to answer my suggest already has
for (int intSuspectCounter = 1; intSuspectCounter < (int)enuSuspects._numSuspects; intSuspectCounter++)
{
enuSuspects eSuspectCounter = (enuSuspects)(((int)eName + (int)enuSuspects._numSuspects - intSuspectCounter) % (int)enuSuspects._numSuspects);
enuSuspects[] eSuspectCardsIKnowThisSuspectHolds = new enuSuspects[0];
for (enuCards eSuspectCardCounter = (enuCards)0;
eSuspectCardCounter < (enuCards)((enuSuspects)(int)enuSuspects._numSuspects);
eSuspectCardCounter++)
{
if (udrAILogic.eNotes[(int)eSuspectCounter, (int)eSuspectCardCounter] == enuNote.check)
{
Array.Resize<enuSuspects>(ref eSuspectCardsIKnowThisSuspectHolds, eSuspectCardsIKnowThisSuspectHolds.Length + 1);
eSuspectCardsIKnowThisSuspectHolds[eSuspectCardsIKnowThisSuspectHolds.Length - 1] = MainForm.getESuspectFromCard(eSuspectCardCounter);
}
}
if (eSuspectCardsIKnowThisSuspectHolds.Length > 0)
{
MainForm.udrSuggestion.eSuspect = eSuspectCardsIKnowThisSuspectHolds[(int)(MainForm.rnd.NextDouble() * 1000) % eSuspectCardsIKnowThisSuspectHolds.Length];
return;
}
else
{
MainForm.udrSuggestion.eSuspect = udrAILogic.eSuspectsLeft[0];
return;
}
}
// this shouldn't happen
// if I reach here : I have no suspect cards and neither do any other suspects in the game
MessageBox.Show("this should not happen : pickSuspectForSuggestion() -> I know the murder suspect is " + udrAILogic.eSuspectsLeft[0].ToString() + " and I can't pick a reasonable card");
// program will flow into the suspect we know committed the murder
}
}
// make an informed decision based on the udrAISuggestion information
if (udrAILogic.udrSuggestionAI.udrSuspectMysteryFrequency.Length == 0) // we know of no "mystery" suspect cards -> pick one we don't know at random
MainForm.udrSuggestion.eSuspect = udrAILogic.eSuspectsLeft[(int)(MainForm.rnd.NextDouble() * 1000) % udrAILogic.eSuspectsLeft.Length];
else if ((int)(MainForm.rnd.NextDouble() * 1000) % 30 == 0) // tweak random frequency according to suspect's intelligence
{ // one 30th of the time -> pick one we don't know at random
MainForm.udrSuggestion.eSuspect = udrAILogic.eSuspectsLeft[(int)(MainForm.rnd.NextDouble() * 1000) % udrAILogic.eSuspectsLeft.Length];
}
else
{
// use udrAISuggestion information
// go around the table in reverse order
for (int intSuspectCounter = 1; intSuspectCounter < (int)enuSuspects._numSuspects; intSuspectCounter++)
{
enuSuspects eSuspectCounter = (enuSuspects)(((int)eName + (int)enuSuspects._numSuspects - intSuspectCounter) % (int)enuSuspects._numSuspects);
classCardsCalled[] cSetsCardsCalled = udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter].cSetsOfCardsCalled;
if (cSetsCardsCalled != null)
for (int intSetsCounter = 0; intSetsCounter < cSetsCardsCalled.Length; intSetsCounter++)
{
// for each set of mystery cards for this suspect
enuCards[] eCardsCalled = cSetsCardsCalled[intSetsCounter].cCardsThatMightHaveBeenShown;
for (int intCardCounter = 0; intCardCounter < eCardsCalled.Length; intCardCounter++)
{
// find the first suspect-card and suggest it
if (classCard.eCardIsASuspect(eCardsCalled[intCardCounter]))
{
MainForm.udrSuggestion.eSuspect = MainForm.getESuspectFromCard(eCardsCalled[intCardCounter]);
return;
}
}
}
}
// if still haven't made a choice -> pick the most common 'mystery' suspect
MainForm.udrSuggestion.eSuspect = MainForm.getESuspectFromCard(udrAILogic.udrSuggestionAI.udrSuspectMysteryFrequency[0].eCards);
}
}
void pickWeaponForSuggestion()
{
if ((eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0) // ai may make a poor random choice from ALL suspects
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 5000 == 0))
{
MainForm.udrSuggestion.eWeapon = (enuWeapons)((int)(MainForm.rnd.NextDouble() * 1000) % (int)enuWeapons._numWeapons);
return;
}
else if (eAILevel == enuAILevel.stupid // ai may make a poor random choice from ALL REMAINING suspects
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0))
{
MainForm.udrSuggestion.eWeapon = udrAILogic.eWeaponsLeft[(int)(MainForm.rnd.NextDouble() * 1000) % udrAILogic.eWeaponsLeft.Length];
return;
}
if (udrAILogic.eWeaponsLeft.Length == 1)
{ // I have narrowed down the number of Weapons to one and now know which Weapon was used in committing the murder
// do not reveal this information to other players
// select a Weapon whose card I have in my hands
if ((int)(MainForm.rnd.NextDouble() * 1000) % 3 == 0)
{ // one third of the time -> pick the one I know is part of the solution
MainForm.udrSuggestion.eWeapon = udrAILogic.eWeaponsLeft[0];
return;
}
else
{
if (eWeaponsIHoldACardFor.Length > 0)
{
MainForm.udrSuggestion.eWeapon = eWeaponsIHoldACardFor[(int)(MainForm.rnd.NextDouble() * 1000) % eWeaponsIHoldACardFor.Length];
return;
}
// I don't hold any Weapon cards
// go around the table in reverse order and pick the first Weapon card I know the last suspect to answer my suggest already has
for (int intSuspectCounter = 1; intSuspectCounter < (int)enuSuspects._numSuspects; intSuspectCounter++)
{
enuSuspects eSuspectCounter = (enuSuspects)(((int)eName + (int)enuSuspects._numSuspects - intSuspectCounter) % (int)enuSuspects._numSuspects);
enuWeapons[] eWeaponCardsIKnowThisSuspectHolds = new enuWeapons[0];
for (enuCards eWeaponCardCounter = (enuCards)(int)enuSuspects._numSuspects;
eWeaponCardCounter < (enuCards)((enuWeapons)((int)enuSuspects._numSuspects + (int)enuWeapons._numWeapons));
eWeaponCardCounter++)
{ // cycle through all weapons cards
if (udrAILogic.eNotes[(int)eSuspectCounter, (int)eWeaponCardCounter] == enuNote.check)
{ // I know this suspect has this weapon-card
Array.Resize<enuWeapons>(ref eWeaponCardsIKnowThisSuspectHolds, eWeaponCardsIKnowThisSuspectHolds.Length + 1);
eWeaponCardsIKnowThisSuspectHolds[eWeaponCardsIKnowThisSuspectHolds.Length - 1] = MainForm.getEWeaponFromCard(eWeaponCardCounter);
}
}
if (eWeaponCardsIKnowThisSuspectHolds.Length > 0)
{
MainForm.udrSuggestion.eWeapon = eWeaponCardsIKnowThisSuspectHolds[(int)(MainForm.rnd.NextDouble() * 1000) % eWeaponCardsIKnowThisSuspectHolds.Length];
return;
}
else
{
MainForm.udrSuggestion.eWeapon = udrAILogic.eWeaponsLeft[0];
return;
}
}
}
// this shouldn't happen
// if I reach here : I have no Weapon cards and neither do any other suspects in the game
MessageBox.Show("this should not happen : pickWeaponForSuggestion() -> I know the murder Weapon is " + udrAILogic.eWeaponsLeft[0].ToString() + " and I can't pick a reasonable card");
// program will flow into the Weapon we know committed the murder
}
// make an informed decision based on the udrAISuggestion information
if (udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency.Length == 0) // we know of no "mystery" Weapon cards -> pick one we don't know at random
MainForm.udrSuggestion.eWeapon = udrAILogic.eWeaponsLeft[(int)(MainForm.rnd.NextDouble() * 1000) % udrAILogic.eWeaponsLeft.Length];
else if ((eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0) // ai may make a poor random choice from ALL REMAINING weapons
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 5000 == 0))// tweak random frequency according to suspect's intelligence
{
MainForm.udrSuggestion.eWeapon = udrAILogic.eWeaponsLeft[(int)(MainForm.rnd.NextDouble() * 1000) % udrAILogic.eWeaponsLeft.Length];
}
else
{
// use udrAISuggestion information
enuCards eSuspectCardSelected = MainForm.getCardFromESuspect(MainForm.udrSuggestion.eSuspect);
for (int intWeaponCounter = 0; intWeaponCounter < udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency.Length; intWeaponCounter++)
{
// if no suspect has both the previously selected 'suspect card' in his list of unknowns AND this 'weapon card' -> select this weapon card
bool bolThisWeaponOk = true;
for (int intSuspectCounter = udrAILogic.udrSuggestionAI.suspectMysteryInfo.Length - 1; intSuspectCounter >= 0; intSuspectCounter--)
{
if ((eCardIsInArray(udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrSuspectCardsMystery,
eSuspectCardSelected) //
&& eCardIsInArray(udrAILogic.udrSuggestionAI.suspectMysteryInfo[intSuspectCounter].udrWeaponCardsMystery,
udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency[intWeaponCounter].eCards)))
{
bolThisWeaponOk = false;
}
}
if (bolThisWeaponOk)
{
MainForm.udrSuggestion.eWeapon = MainForm.getEWeaponFromCard(udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency[intWeaponCounter].eCards);
return;
}
}
// no suspect has only one
// scan all weapons left
// pick one that is not in the list of unknowns
enuWeapons[] eWeaponArray = new enuWeapons[0];
for (int intWeaponCounter = 0; intWeaponCounter < udrAILogic.eWeaponsLeft.Length; intWeaponCounter++)
{
if (!eCardIsInArray(udrAILogic.udrSuggestionAI.udrWeaponMysteryFrequency, MainForm.getCardFromEWeapon(udrAILogic.eWeaponsLeft[intWeaponCounter])))
{
Array.Resize<enuWeapons>(ref eWeaponArray, eWeaponArray.Length + 1);
eWeaponArray[eWeaponArray.Length - 1] = udrAILogic.eWeaponsLeft[intWeaponCounter];
}
}
if (eWeaponArray.Length > 0)
{ // there are a few options
MainForm.udrSuggestion.eWeapon = eWeaponArray[((int)MainForm.rnd.NextDouble() * 10000) % eWeaponArray.Length];
return;
}
// the only weapons left are possibly in the hands of the same suspect
// pick one at random
MainForm.udrSuggestion.eWeapon = udrAILogic.eWeaponsLeft[((int)MainForm.rnd.NextDouble() * 10000) % udrAILogic.eWeaponsLeft.Length];
return;
}
}
bool eCardIsInArray(udtSuggestionAI_frequenCards[] udrFreqCardsArray, enuCards eCard)
{
if (udrFreqCardsArray == null)
return false;
for (int intCardCounter = 0; intCardCounter < udrFreqCardsArray.Length; intCardCounter++)
{
if (udrFreqCardsArray[intCardCounter].eCards == eCard)
return true;
}
return false;
}
bool ICanLeaveThisRoom()
{
classRoom cRoom = MainForm.cRooms[(int)eRoom];
for (int intDoorCounter = 0; intDoorCounter < cRoom.ptDoors.Length; intDoorCounter++)
{
if (cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor == enuDir.secretPassage)
return true;
else
{
Point ptNext = MainForm.movePoint(cRoom.ptDoors[intDoorCounter], cFloor[cRoom.ptDoors[intDoorCounter].X, cRoom.ptDoors[intDoorCounter].Y].dirDoor);
if (MainForm.floorTileIsFree(ptNext))
return true;
}
}
return false;
}
bool PickDestinationTile()
{
// start from destination room
// travel back along shortest path until reach a tile that is included in the allowable tiles
if (eRoom < enuRooms._numRooms)
{
if (!ICanLeaveThisRoom())
return false;
}
Point ptCurrentTile = new Point(0, 0);
bool bolAllowSecretPassage =(eRoom != enuRooms.start
&& eRoom != enuRooms.tiles
&& (udrAILogic.eDestinationRoom != MainForm.cRooms[(int)eRoom].oppositeCornerRoom()));
bool bolThereIsADoorOutOfDestinationRoom = getBestDoorOutThisRoom(udrAILogic.eDestinationRoom, ref ptCurrentTile,bolAllowSecretPassage);
if (ptCurrentTile.X < 0) // using secret passage -> decode roomID -> get best door out of next room
{
enuRooms eRoomOnOtherSideOfPassage = (enuRooms)(Math.Abs(ptCurrentTile.X) % ((int)enuRooms._numRooms));
if (eRoomOnOtherSideOfPassage == udrAILogic.eDestinationRoom)
{
switch (eRoom)
{
case enuRooms.Study:
udrAILogic.ptDestinationTile = new Point(0, 0);
return true;
case enuRooms.Lounge:
udrAILogic.ptDestinationTile = new Point(23, 0);
return true;
case enuRooms.Kitchen:
udrAILogic.ptDestinationTile = new Point(23, 23);
return true;
case enuRooms.Conservatory:
udrAILogic.ptDestinationTile = new Point(0, 23);
return true;
}
}
else if (eRoomOnOtherSideOfPassage == MainForm.cRooms[(int)udrAILogic.eDestinationRoom].oppositeCornerRoom())
{
getBestDoorOutThisRoom(eRoomOnOtherSideOfPassage, ref ptCurrentTile, false);
}
else
getBestDoorOutThisRoom((enuRooms)(Math.Abs(ptCurrentTile.X) % (int)enuRooms._numRooms), ref ptCurrentTile, true);
}
else if (cSEAllowableMoves[ptCurrentTile.X, ptCurrentTile.Y] == null)
{
ptCurrentTile = MainForm.movePoint(ptCurrentTile, classSuspect.cFloor[ptCurrentTile.X, ptCurrentTile.Y].dirDoor);
}
while (cSEAllowableMoves[ptCurrentTile.X, ptCurrentTile.Y] == null)
{
if (classSuspect.cFloor[ptCurrentTile.X, ptCurrentTile.Y].eType == enuFloor.door)
{
getBestDoorOutThisRoom(classSuspect.cFloor[ptCurrentTile.X, ptCurrentTile.Y].eRoom, ref ptCurrentTile, true);
if (ptCurrentTile.X < 0)
{ // using secret passage
enuRooms eThisRoom = (enuRooms)((int)Math.Abs(ptCurrentTile.X) % (int)enuRooms._numRooms);
getBestDoorOutThisRoom(eThisRoom, ref ptCurrentTile, true);
}
else if (cSEAllowableMoves[ptCurrentTile.X, ptCurrentTile.Y] == null)
{
ptCurrentTile = MainForm.movePoint(ptCurrentTile, classSuspect.cFloor[ptCurrentTile.X, ptCurrentTile.Y].dirDoor);
}
}
else
ptCurrentTile = MainForm.movePoint(ptCurrentTile, cShortestPath[ptCurrentTile.X, ptCurrentTile.Y].SrcDir);
}
udrAILogic.ptDestinationTile = ptCurrentTile;
return true;
}
bool getBestDoorOutThisRoom(enuRooms eRoom, ref Point ptTileOfBestDoor) { return getBestDoorOutThisRoom(eRoom, ref ptTileOfBestDoor, true); }
bool getBestDoorOutThisRoom(enuRooms eThisRoom, ref Point ptTileOfBestDoor, bool bolAllowSecretPassage)
{
classRoom cRoom = MainForm.cRooms[(int)eThisRoom];
Point[] ptDoors = cRoom.getValidDoors(bolAllowSecretPassage);
// cancel blocked doors
for (int intDoorCounter = 0; intDoorCounter < ptDoors.Length; intDoorCounter++)
{
Point ptTileOutsideDoor = MainForm.movePoint(ptDoors[intDoorCounter], cFloor[ptDoors[intDoorCounter].X, ptDoors[intDoorCounter].Y].dirDoor);
if (!MainForm.floorTileIsFree(ptTileOutsideDoor) && ptTile != ptTileOutsideDoor) // if the door is not blocked (by some other suspect)
{ // this door is blocked
ptDoors[intDoorCounter] = ptDoors[ptDoors.Length - 1];
Array.Resize<Point>(ref ptDoors, ptDoors.Length - 1);
}
}
if (ptDoors.Length == 0)
return false;
ptTileOfBestDoor = ptDoors[0]; // start with door 0th index
if (classSuspect.cFloor[ptTileOfBestDoor.X, ptTileOfBestDoor.Y].dirDoor == enuDir.secretPassage)
if (ptDoors.Length > 1)
ptTileOfBestDoor = ptDoors[1];
else
{
if (bolAllowSecretPassage)
{
switch (cRoom.name)
{ // encode destination Room's ID into door's "point"
case enuRooms.Lounge:
ptTileOfBestDoor = new Point(-6, -6);
return true;
case enuRooms.Study:
ptTileOfBestDoor = new Point(-4, -4);
return true;
case enuRooms.Kitchen:
ptTileOfBestDoor = new Point(-(int)enuRooms._numRooms, -(int)enuRooms._numRooms); // study's ID is 'zero' -> decode with Modulo of absolute value
return true;
case enuRooms.Conservatory:
ptTileOfBestDoor = new Point(-2, -2);
return true;
}
}
else
return false;
}
for (int intDoorCounter = 0; intDoorCounter < ptDoors.Length; intDoorCounter++)
{
Point ptDoor = ptDoors[intDoorCounter];
if (classSuspect.cFloor[ptDoor.X, ptDoor.Y].dirDoor == enuDir.secretPassage)
{ // code roomID of room on other side of secret passage into x & y values of 'best door' point
Point ptNextBestDoor = new Point(0, 0);
// test shortest path travel cost for this door
switch (cRoom.name)
{
case enuRooms.Lounge:
ptNextBestDoor = new Point(0, 23);
break;
case enuRooms.Study:
ptNextBestDoor = new Point(23, 23);
break;
case enuRooms.Kitchen:
ptNextBestDoor = new Point(0, 0);
break;
case enuRooms.Conservatory:
ptNextBestDoor = new Point(23, 0);
break;
}
if (cShortestPath[ptNextBestDoor.X, ptNextBestDoor.Y] != null
&& cShortestPath[ptNextBestDoor.X, ptNextBestDoor.Y].intTurns * 3 + cShortestPath[ptNextBestDoor.X, ptNextBestDoor.Y].intSteps
< cShortestPath[ptTileOfBestDoor.X, ptTileOfBestDoor.Y].intTurns * 3 + cShortestPath[ptTileOfBestDoor.X, ptTileOfBestDoor.Y].intSteps)
{ // using this secret passage is a short cut to destination
switch (cRoom.name)
{ // encode destination Room's ID into door's "point"
case enuRooms.Lounge:
ptTileOfBestDoor = new Point(-6, -6);
return true;
case enuRooms.Study:
ptTileOfBestDoor = new Point(-4, -4);
return true;
case enuRooms.Kitchen:
ptTileOfBestDoor = new Point(-(int)enuRooms._numRooms, -(int)enuRooms._numRooms); // study's ID is 'zero' -> decode with Modulo of absolute value
return true;
case enuRooms.Conservatory:
ptTileOfBestDoor = new Point(-2, -2);
return true;
}
return true;
}
}
else
{
Point ptNextTile = MainForm.movePoint(ptDoor, classSuspect.cFloor[ptDoor.X, ptDoor.Y].dirDoor);
if (cShortestPath[ptNextTile.X, ptNextTile.Y] != null)
if (cShortestPath[ptNextTile.X, ptNextTile.Y].intTurns * 3 + cShortestPath[ptNextTile.X, ptNextTile.Y].intSteps
<
cShortestPath[ptTileOfBestDoor.X, ptTileOfBestDoor.Y].intTurns * 3 + cShortestPath[ptTileOfBestDoor.X, ptTileOfBestDoor.Y].intSteps)
{
ptTileOfBestDoor = ptDoors[intDoorCounter];
}
}
}
return true;
}
void PickDestinationRoom()
{
classTurnsReachRoom[] cNumTurnsReachableRooms = new classTurnsReachRoom[0];
string strReachableRooms = ".";
for (int intRoomCounter = 0; intRoomCounter < cNumTurnsToReachRooms.Length; intRoomCounter++)
{
if (cNumTurnsToReachRooms[intRoomCounter].getCost > 0 && cNumTurnsToReachRooms[intRoomCounter].getCost < 1000)
{
Array.Resize<classTurnsReachRoom>(ref cNumTurnsReachableRooms, cNumTurnsReachableRooms.Length + 1);
cNumTurnsReachableRooms[cNumTurnsReachableRooms.Length - 1] = cNumTurnsToReachRooms[intRoomCounter];
strReachableRooms += cNumTurnsToReachRooms[intRoomCounter].ToString().ToUpper() + ".";
}
}
cNumTurnsToReachRooms = cNumTurnsReachableRooms;
if ((eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0) // ai may make a poor random choice from ALL remaining accessible rooms
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 5000 == 0))
{
if (cNumTurnsToReachRooms.Length > 0)
{
udrAILogic.eDestinationRoom = (cNumTurnsToReachRooms[((int)(MainForm.rnd.NextDouble() * 1000) % cNumTurnsToReachRooms.Length)].eRoom);
}
else
{
udrAILogic.eDestinationRoom = eRoom;
}
return;
}
// reorder list of rooms in ascending number of turns
int intBestIndex;
int intInnerLoop, intOuterLoop;
for (intOuterLoop = 0; intOuterLoop < cNumTurnsToReachRooms.Length - 1; intOuterLoop++)
{
intBestIndex = intOuterLoop;
for (intInnerLoop = intOuterLoop + 1; intInnerLoop < cNumTurnsToReachRooms.Length; intInnerLoop++)
{
if (cNumTurnsToReachRooms[intInnerLoop].getCost < cNumTurnsToReachRooms[intBestIndex].getCost)
intBestIndex = intInnerLoop;
}
if (intBestIndex != intOuterLoop)
{
classTurnsReachRoom cTemp = cNumTurnsToReachRooms[intOuterLoop];
cNumTurnsToReachRooms[intOuterLoop] = cNumTurnsToReachRooms[intBestIndex];
cNumTurnsToReachRooms[intBestIndex] = cTemp;
}
}
if (cNumTurnsToReachRooms.Length == 0)
{
udrAILogic.eDestinationRoom = eRoom;
return;
}
if (udrAILogic.eRoomsLeft.Length == 1)
{ // I have narrowed down the possible room solutions and now know which room the murder was committed in
// avoid revealing this information to other players by choosing another room
udrAILogic.eDestinationRoom = cNumTurnsToReachRooms[0].eRoom; // default is the nearest room
if ((eAILevel == enuAILevel.stupid && (int)(MainForm.rnd.NextDouble() * 1000) % 2 == 0) // ai may make a poor choice and go to the nearest room
|| (eAILevel == enuAILevel.dull && (int)(MainForm.rnd.NextDouble() * 1000) % 5 == 0)
|| (eAILevel == enuAILevel.average && (int)(MainForm.rnd.NextDouble() * 1000) % 50 == 0)
|| (eAILevel == enuAILevel.bright && (int)(MainForm.rnd.NextDouble() * 1000) % 500 == 0)
|| (eAILevel == enuAILevel.genius && (int)(MainForm.rnd.NextDouble() * 1000) % 5000 == 0))
return;
if (eRoomsIHoldACardFor.Length > 0)
{ // pick a room for which I hold the card (not give away the murder-room solution)
for (int intRoomCounter = 0; intRoomCounter < cNumTurnsToReachRooms.Length; intRoomCounter++)
{ // scan through the list in order ranked by distance (nearest first)
if (cNumTurnsToReachRooms[intRoomCounter].getCost > 0)
{ // exclude the room I am in
for (int intCardRoomsIHaveCounter = 0; intCardRoomsIHaveCounter < eRoomsIHoldACardFor.Length; intCardRoomsIHaveCounter++)
{ // compare to the rooms I have a card for
if (eRoomsIHoldACardFor[intCardRoomsIHaveCounter] == cNumTurnsToReachRooms[intRoomCounter].eRoom)
{ // I have this room's card -> go there
udrAILogic.eDestinationRoom = cNumTurnsToReachRooms[intRoomCounter].eRoom;
return;
}
}
}
}
}
// if I am still here it is because I do not hold any room cards
// go around the table and pick a room which I know player to my right hold
for (int intSuspectCounter = 1; intSuspectCounter < (int)enuSuspects._numSuspects; intSuspectCounter++)
{
enuSuspects eSuspectCounter = (enuSuspects)((int)eName + (int)enuSuspects._numSuspects - intSuspectCounter);
enuRooms[] eRoomsIKnowThisSuspectHas = new enuRooms[0];
for (enuCards eCardCounter = (enuCards)((int)enuSuspects._numSuspects + (int)enuWeapons._numWeapons);
eCardCounter < enuCards._numCards;
eCardCounter++)
{ // scan through all room cards
if (strReachableRooms.Contains(eCardCounter.ToString().ToUpper())) // if it is a reachable room
{
if (udrAILogic.eNotes[(int)eSuspectCounter, (int)eCardCounter] == enuNote.check)
{ // my notes tell me this suspect has this room card in his hands
Array.Resize<enuRooms>(ref eRoomsIKnowThisSuspectHas, eRoomsIKnowThisSuspectHas.Length + 1);
eRoomsIKnowThisSuspectHas[eRoomsIKnowThisSuspectHas.Length - 1] = MainForm.getERoomFromCard(eCardCounter);
}
}
}
for (int intRoomCounter = 0; intRoomCounter < cNumTurnsToReachRooms.Length; intRoomCounter++)
{ // scan through the list in order ranked by distance (nearest first)
if (cNumTurnsToReachRooms[intRoomCounter].getCost > 0)
{ // exclude the room I am in
for (int intCardRoomsThisSuspectHasCounter = 0; intCardRoomsThisSuspectHasCounter < eRoomsIKnowThisSuspectHas.Length; intCardRoomsThisSuspectHasCounter++)
{ // compare to the rooms I have a card for
if (eRoomsIKnowThisSuspectHas[intCardRoomsThisSuspectHasCounter] == cNumTurnsToReachRooms[intRoomCounter].eRoom)
{ // I have this room's card -> go there
udrAILogic.eDestinationRoom = cNumTurnsToReachRooms[intRoomCounter].eRoom;
return;
}
}
}
}
}
}
// scan list until find a good choice
udrAILogic.eDestinationRoom = cNumTurnsToReachRooms[0].eRoom; // default is the nearest room
for (int intRoomCounter = 0; intRoomCounter < cNumTurnsToReachRooms.Length; intRoomCounter++)
{
if (cNumTurnsToReachRooms[intRoomCounter].getCost > 0)
{
if (eRoomIsStillPossibleSolution(cNumTurnsToReachRooms[intRoomCounter].eRoom))
{
udrAILogic.eDestinationRoom = cNumTurnsToReachRooms[intRoomCounter].eRoom;
return;
}
}
}
}
bool eRoomIsStillPossibleSolution(enuRooms eRoom)
{
for (int intRoomCounter = 0; intRoomCounter < udrAILogic.eRoomsLeft.Length; intRoomCounter++)
if (eRoom == udrAILogic.eRoomsLeft[intRoomCounter])
return true;
return false;
}
bool eWeaponIsStillPossibleSolution(enuWeapons eWeapon)
{
for (int intWeaponCounter = 0; intWeaponCounter < udrAILogic.eWeaponsLeft.Length; intWeaponCounter++)
if (eWeapon == udrAILogic.eWeaponsLeft[intWeaponCounter])
return true;
return false;
}
bool eSuspectIsStillPossibleSolution(enuSuspects eSuspect)
{
for (int intSuspectCounter = 0; intSuspectCounter < udrAILogic.eSuspectsLeft.Length; intSuspectCounter++)
if (eSuspect == udrAILogic.eSuspectsLeft[intSuspectCounter])
return true;
return false;
}
public void setAI()
{
eRoomsIHoldACardFor = new enuRooms[0];
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
if (cCards[intCardCounter].IsARoom)
{
Array.Resize<enuRooms>(ref eRoomsIHoldACardFor, eRoomsIHoldACardFor.Length + 1);
eRoomsIHoldACardFor[eRoomsIHoldACardFor.Length - 1] = MainForm.getERoomFromCard(cCards[intCardCounter].eCardName);
}
}
eSuspectsIHoldACardFor = new enuSuspects[0];
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
if (cCards[intCardCounter].IsASuspect)
{
Array.Resize<enuSuspects>(ref eSuspectsIHoldACardFor, eSuspectsIHoldACardFor.Length + 1);
eSuspectsIHoldACardFor[eSuspectsIHoldACardFor.Length - 1] = MainForm.getESuspectFromCard(cCards[intCardCounter].eCardName);
}
}
eWeaponsIHoldACardFor = new enuWeapons[0];
for (int intCardCounter = 0; intCardCounter < cCards.Length; intCardCounter++)
{
if (cCards[intCardCounter].IsAWeapon)
{
Array.Resize<enuWeapons>(ref eWeaponsIHoldACardFor, eWeaponsIHoldACardFor.Length + 1);
eWeaponsIHoldACardFor[eWeaponsIHoldACardFor.Length - 1] = MainForm.getEWeaponFromCard(cCards[intCardCounter].eCardName);
}
}
for (enuSuspects eSuspectCounter = (enuSuspects)0; eSuspectCounter < enuSuspects._numSuspects; eSuspectCounter++)
udrAILogic.cSuspectsUnknowns[(int)eSuspectCounter] = new classSuspectCardsCalled();
}
}
public class classWeapon
{
public enuWeapons eName;
public Point pt;
enuRooms _eRoom;
public classWeapon(enuWeapons weaponName)
{
eName = weaponName;
_eRoom = enuRooms._numRooms;
}
public enuRooms eRoom
{
get { return _eRoom; }
set
{
_eRoom = value;
}
}
}
public class classCard
{
public enuCardType eType;
public enuCards eCardName;
public classSuspect cSuspect;
public classRotatedImage cBmp = new classRotatedImage();
formClue MainForm;
public udtAnimationInfo udrAnimationInfo;
public classCard(formClue mainform, enuCards Name)
{
MainForm = mainform;
eCardName = Name;
setCardType();
setImage();
}
string getRootDirectory(string strThisDirectory)
{
int intIndexBackSlash = strThisDirectory.LastIndexOf("\\");
if (intIndexBackSlash > 0)
return strThisDirectory.Substring(0, intIndexBackSlash);
return "";
}
string FileExists(string strImageName)
{
string strDir = System.IO.Directory.GetCurrentDirectory();
string strFilename = strImageName + ".rBMP";
string strFilenameAndDirectory = strDir + "\\" + strFilename;
if (System.IO.File.Exists(strFilenameAndDirectory))
return strFilenameAndDirectory;
else
{
while (strDir.Length > 0)
{
strDir = getRootDirectory(strDir);
strFilenameAndDirectory = strDir + "\\" + strFilename;
if (System.IO.File.Exists(strFilenameAndDirectory))
return strFilenameAndDirectory;
}
}
return strImageName;
}
void setImage()
{
string strCurrentDir_Filename = System.IO.Directory.GetCurrentDirectory() + "\\" + eCardName.ToString() + ".rbmp";
bool bolSaveCurrentDir = false;
if (!System.IO.File.Exists(strCurrentDir_Filename))
bolSaveCurrentDir = true;
MainForm.advanceProBar();
string strFilename = FileExists(eCardName.ToString());
if (System.IO.File.Exists(strFilename))
{
cBmp.loadBaseImages(strFilename);
if (bolSaveCurrentDir)
cBmp.saveBaseImages(strCurrentDir_Filename);
}
else
{
double dblFractionSize = 0.75;
Size sz = new Size((int)(Clue_CS2010.Properties.Resources.cardback.Width * dblFractionSize), (int)(Clue_CS2010.Properties.Resources.cardback.Height * dblFractionSize));
switch (eCardName)
{
/// suspects
case enuCards.ColMustard:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardSuspectColMustard, sz));
break;
case enuCards.ProfPlum:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardSuspectProfPlum, sz));
break;
case enuCards.RevGreen:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardSuspectRevGreen, sz));
break;
case enuCards.MrsPeacock:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardSuspectMrsPeacock, sz));
break;
case enuCards.MissScarlet:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardSuspectMissScarlet, sz));
break;
case enuCards.MrsWhite:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardSuspectMrsWhite, sz));
break;
/// weapons
case enuCards.Knife:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardWeaponKnife, sz));
break;
case enuCards.Candlestick:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardWeaponCandleStick, sz));
break;
case enuCards.Revolver:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardWeaponRevolver, sz));
break;
case enuCards.Rope:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardWeaponRope, sz));
break;
case enuCards.LeadPipe:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardWeaponLeadPipe, sz));
break;
case enuCards.Wrench:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardWeaponWrench, sz));
break;
/// rooms
case enuCards.Hall:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomHall, sz));
break;
case enuCards.Lounge:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomLounge, sz));
break;
case enuCards.DiningRoom:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomDiningRoom, sz));
break;
case enuCards.Kitchen:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomKitchen, sz));
break;
case enuCards.BallRoom:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomBallroom, sz));
break;
case enuCards.Conservatory:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomConservatory, sz));
break;
case enuCards.BilliardRoom:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardBilliardRoom, sz));
break;
case enuCards.Library:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomLibrary, sz));
break;
case enuCards.Study:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.CardRoomStudy, sz));
break;
case enuCards.Unknown:
cBmp.createBaseImage(new Bitmap(Clue_CS2010.Properties.Resources.cardback, sz));
break;
}
cBmp.getImage(0); MainForm.advanceProBar();
cBmp.getImage(1); MainForm.advanceProBar();
cBmp.getImage(2); MainForm.advanceProBar();
cBmp.getImage(3); MainForm.advanceProBar();
cBmp.saveBaseImages(strCurrentDir_Filename);
}
}
/// <summary>
/// assumes card starts with initial velocity, slides across table and slowly stops
/// </summary>
/// <param name="ptStart">start position on the screen</param>
/// <param name="ptEnd">end position on the screen</param>
/// <param name="intNumSteps">number of clock cycles to reach end position and v=0 given a constant negative acceleration</param>
public void setAnimationVelocity(Point ptStart, Point ptEnd, int intNumSteps)
{
udrAnimationInfo.ptStart = ptStart;
udrAnimationInfo.ptEnd = ptEnd;
udrAnimationInfo.dblTravelAngle = classMath.arcTan(ptEnd.X - ptStart.X, ptEnd.Y - ptStart.Y);
udrAnimationInfo.dblTravelDistance = Math.Sqrt(Math.Pow(ptEnd.X - ptStart.X, 2) + Math.Pow(ptEnd.Y - ptStart.Y, 2));
udrAnimationInfo.dblTravelAcceleration = -10;
udrAnimationInfo.intMaxSteps = 25 + (int)(MainForm.rnd.NextDouble() * 1000) % 20;
udrAnimationInfo.dblTravelInitialVelocity = -udrAnimationInfo.intMaxSteps * udrAnimationInfo.dblTravelAcceleration;
}
void setCardType()
{
int intCardNum = (int)eCardName;
if (intCardNum < 6)
eType = enuCardType.Suspect;
else if (intCardNum < 12)
eType = enuCardType.weapon;
else
eType = enuCardType.room;
SetIsARoom();
SetIsAWeapon();
SetIsASuspect();
}
bool bolIsARoom;
public bool IsARoom
{
get { return bolIsARoom; }
}
void SetIsARoom()
{
bolIsARoom = eCardIsARoom(eCardName);
}
public static bool eCardIsARoom(enuCards eCard)
{
return ((int)eCard >= (int)enuSuspects._numSuspects + (int)enuWeapons._numWeapons);
}
bool bolIsAWeapon;
public bool IsAWeapon
{
get { return bolIsAWeapon; }
}
void SetIsAWeapon()
{
bolIsAWeapon = eCardIsAWeapon(eCardName);
}
public static bool eCardIsAWeapon(enuCards eCard)
{
return ((int)eCard >= (int)enuSuspects._numSuspects && (int)eCard < (int)enuSuspects._numSuspects + (int)enuWeapons._numWeapons);
}
bool bolIsASuspect;
public bool IsASuspect
{
get { return bolIsASuspect; }
}
void SetIsASuspect()
{
bolIsASuspect = eCardIsASuspect(eCardName);
}
public static bool eCardIsASuspect(enuCards eCard)
{
return ((int)eCard < (int)enuSuspects._numSuspects);
}
public static enuCards getECardFromERoom(enuRooms eThisRoom) { return (enuCards)((int)eThisRoom + (int)enuSuspects._numSuspects + (int)enuWeapons._numWeapons); }
public static enuCards getECardFromESuspect(enuSuspects eThisSuspect) { return (enuCards)(int)eThisSuspect; }
public static enuCards getECardFromEWeapon(enuWeapons eThisWeapon) { return (enuCards)((int)eThisWeapon + (int)enuSuspects._numSuspects); }
}
public class classFloor
{
public enuFloor eType;
public enuDir dirDoor;
public enuRooms eRoom;
}
public class classButton
{
static Brush brWhite;
public Point pt;
public Size sz;
public Color clrBorder;
public string strText;
public Font fnt;
public Bitmap bmpMyself;
public Bitmap bmpMyHighlight;
public PictureBox picBox;
public formClue mainForm;
public enuMode eMode;
public classNote cNote;
public enuButtons eButtonName;
public classButton(formClue MainForm, ref PictureBox picField, enuMode Mode, Point Pt, Color ClrBorder, string text, Font myFont)
{
picBox = picField;
eMode = Mode;
mainForm = MainForm;
pt = Pt;
clrBorder = ClrBorder;
strText = text;
fnt = myFont;
if (text.Length > 0 && fnt != null)
setImage();
if (brWhite == null)
brWhite = new SolidBrush(Color.White);
}
public string Text
{
get { return strText; }
set
{
strText = value;
setImage();
}
}
void setImage()
{
bmpMyself = mainForm.getTextImage(strText, fnt);
Rectangle recBorder = new Rectangle(0, 0, bmpMyself.Width - 1, bmpMyself.Height - 7);
using (Graphics g = Graphics.FromImage(bmpMyself))
{
g.DrawRectangle(new Pen(clrBorder), recBorder);
}
bmpMyHighlight = new Bitmap(bmpMyself);
using (Graphics g = Graphics.FromImage(bmpMyHighlight))
g.DrawRectangle(new Pen(Color.Red), recBorder);
sz = recBorder.Size;
}
public void draw()
{
if (mainForm.eMode != eMode && eMode != enuMode.any)
return;
if (bmpMyself == null || bmpMyHighlight == null)
setImage();
Bitmap bmpTemp = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bmpTemp))
g.DrawImage(bmpMyself, pt);
picBox.Image = bmpTemp; picBox.Refresh();
}
public void highlight()
{
if (mainForm.eMode != eMode && eMode != enuMode.any)
return;
if (bmpMyself == null || bmpMyHighlight == null)
setImage();
Bitmap bmpTemp = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bmpTemp))
g.DrawImage(bmpMyHighlight, pt);
picBox.Image = bmpTemp;
}
public void erase()
{
Bitmap bmpTemp = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bmpTemp))
g.FillRectangle(brWhite, new Rectangle(pt, sz));
picBox.Image = bmpTemp;
}
}
public class classNote
{
public enuNote eNote;
enuSuspects eSuspect;
enuCards eCard;
formClue mainForm;
PictureBox picBox;
public enuMode eMode;
public Point pt;
Bitmap bmpMyself, bmpMyHighlight;
static Bitmap[] bmpSuspects;
static Bitmap[] bmpNotes;
static Bitmap bmpHighlight;
public bool bolUpdateImage = true;
public classNote(formClue MainForm, ref PictureBox picField, enuMode Mode, enuSuspects Suspect, enuCards Card)
{
mainForm = MainForm;
picBox = picField;
eMode = Mode;
eSuspect = Suspect;
eCard = Card;
if (bmpSuspects == null)
initImages();
placeButton();
}
void initImages()
{
bmpSuspects = new Bitmap[(int)enuSuspects._numSuspects];
bmpSuspects[(int)enuSuspects.ColMustard] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_ColMustard); bmpSuspects[(int)enuSuspects.ColMustard].MakeTransparent();
bmpSuspects[(int)enuSuspects.MissScarlet] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_MissScarlet); bmpSuspects[(int)enuSuspects.MissScarlet].MakeTransparent();
bmpSuspects[(int)enuSuspects.MrsPeacock] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_MrsPeacock); bmpSuspects[(int)enuSuspects.MrsPeacock].MakeTransparent();
bmpSuspects[(int)enuSuspects.MrsWhite] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_MrsWhite); bmpSuspects[(int)enuSuspects.MrsWhite].MakeTransparent();
bmpSuspects[(int)enuSuspects.ProfPlum] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_ProfPlum); bmpSuspects[(int)enuSuspects.ProfPlum].MakeTransparent();
bmpSuspects[(int)enuSuspects.RevGreen] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_RevGreen); bmpSuspects[(int)enuSuspects.RevGreen].MakeTransparent();
bmpNotes = new Bitmap[(int)enuNote._numNotes];
bmpNotes[(int)enuNote.blank] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_blank); bmpNotes[(int)enuNote.blank].MakeTransparent();
bmpNotes[(int)enuNote.check] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_check); bmpNotes[(int)enuNote.check].MakeTransparent();
bmpNotes[(int)enuNote.question] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_questionMark); bmpNotes[(int)enuNote.question].MakeTransparent();
bmpNotes[(int)enuNote.X] = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_X); bmpNotes[(int)enuNote.X].MakeTransparent();
bmpHighlight = new Bitmap(Clue_CS2010.Properties.Resources.noteBox_highlight); bmpHighlight.MakeTransparent();
}
void placeButton()
{
int intY = 0;
switch (eCard)
{
case enuCards.ColMustard:
intY = 39;
break;
case enuCards.ProfPlum:
intY = 65;
break;
case enuCards.RevGreen:
intY = 91;
break;
case enuCards.MrsPeacock:
intY = 119;
break;
case enuCards.MissScarlet:
intY = 145;
break;
case enuCards.MrsWhite:
intY = 171;
break;
case enuCards.Knife:
intY = 221;
break;
case enuCards.Candlestick:
intY = 247;
break;
case enuCards.Revolver:
intY = 273;
break;
case enuCards.Rope:
intY = 301;
break;
case enuCards.LeadPipe:
intY = 327;
break;
case enuCards.Wrench:
intY = 353;
break;
case enuCards.Hall:
intY = 403;
break;
case enuCards.Lounge:
intY = 429;
break;
case enuCards.DiningRoom:
intY = 455;
break;
case enuCards.Kitchen:
intY = 483;
break;
case enuCards.BallRoom:
intY = 509;
break;
case enuCards.Conservatory:
intY = 535;
break;
case enuCards.BilliardRoom:
intY = 563;
break;
case enuCards.Library:
intY = 589;
break;
case enuCards.Study:
intY = 615;
break;
}
int intX = 240 + (int)eSuspect * 25;
pt = new Point(intX, intY);
setMyImages();
}
public enuSuspects Suspect
{
get { return eSuspect; }
}
public enuCards Card
{
get { return eCard; }
}
public enuNote Note
{
get { return eNote; }
set
{
if (eNote != value)
{
eNote = value;
//setMyImages();
//draw();
bolUpdateImage = true;
}
}
}
public void draw()
{
if (mainForm.eMode != eMode && eMode != enuMode.any)
return;
if (bmpMyself == null || bmpMyHighlight == null || bolUpdateImage)
setMyImages();
Bitmap bmpTemp = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bmpTemp))
g.DrawImage(bmpMyself, pt);
picBox.Image = bmpTemp; picBox.Refresh();
}
public void highlight()
{
if (mainForm.eMode != eMode && eMode != enuMode.any)
return;
if (bmpMyself == null || bmpMyHighlight == null || bolUpdateImage)
setMyImages();
Bitmap bmpTemp = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bmpTemp))
g.DrawImage(bmpMyHighlight, pt);
picBox.Image = bmpTemp;
}
public void setMyImages()
{
bolUpdateImage = false;
bmpMyself = new Bitmap(25, 25);
using (Graphics g = Graphics.FromImage(bmpMyself))
{
Rectangle recSrc = new Rectangle(pt.X, pt.Y, 25, 25);
Rectangle recDest = new Rectangle(0, 0, 25, 25);
g.DrawImage(mainForm.bmpNotebook, recDest, recSrc, GraphicsUnit.Pixel);
g.DrawImage(bmpSuspects[(int)eSuspect], new Point(0, 0));
g.DrawImage(bmpNotes[(int)eNote], new Point(0, 0));
}
bmpMyHighlight = new Bitmap(bmpMyself);
using (Graphics g = Graphics.FromImage(bmpMyHighlight))
g.DrawImage(bmpHighlight, new Point(0, 0));
}
}
public class classRotatedImage
{
Bitmap[] bmp = new Bitmap[16];
public void loadBaseImages(string strFilename)
{
if (System.IO.File.Exists(strFilename))
{
FileStream fs = new FileStream(strFilename, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
for (int intBaseImageCounter = 0; intBaseImageCounter < 4; intBaseImageCounter++)
{
bmp[intBaseImageCounter] = (Bitmap)formatter.Deserialize(fs);
}
fs.Close();
}
}
public void saveBaseImages(string strFilename)
{
if (System.IO.File.Exists(strFilename))
System.IO.File.Delete(strFilename);
FileStream fs = new FileStream(strFilename, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
for (int intBaseImageCounter = 0; intBaseImageCounter < 4; intBaseImageCounter++)
{
if (bmp[intBaseImageCounter] == null)
bmp[intBaseImageCounter] = getImage(intBaseImageCounter);
formatter.Serialize(fs, bmp[intBaseImageCounter]);
}
fs.Close();
}
public Bitmap getImage(int intIndex)
{
if (bmp[0] == null)
return null;
if (bmp[intIndex] != null)
return bmp[intIndex];
if (intIndex < 4)
{
bmp[intIndex] = rotate(bmp[0], Math.PI / 8.0 * (double)intIndex);
}
else
{
int intBaseIndex = intIndex % 4;
bmp[intIndex] = new Bitmap(getImage(intBaseIndex));
int intQuarterRotations = (int)Math.Floor((double)intIndex / 4.0);
switch (intQuarterRotations)
{
case 1:
bmp[intIndex].RotateFlip(RotateFlipType.Rotate270FlipNone);
break;
case 2:
bmp[intIndex].RotateFlip(RotateFlipType.Rotate180FlipNone);
break;
case 3:
bmp[intIndex].RotateFlip(RotateFlipType.Rotate90FlipNone);
break;
}
}
bmp[intIndex].MakeTransparent();
return bmp[intIndex];
}
public void createBaseImage(Bitmap bmpBaseImage)
{
bmp[0] = bmpBaseImage;
using (Graphics g = Graphics.FromImage(bmp[0]))
g.DrawRectangle(new Pen(Color.White, 2), new Rectangle(0, 0, bmp[0].Width - 1, bmp[0].Height - 1));
bmp[0].MakeTransparent();
}
public void createBaseImage(string strFilename)
{
if (System.IO.File.Exists(strFilename))
{
bmp[0] = new Bitmap(strFilename);
using (Graphics g = Graphics.FromImage(bmp[0]))
g.DrawRectangle(new Pen(Color.White, 2), new Rectangle(0, 0, bmp[0].Width - 1, bmp[0].Height - 1));
bmp[0].MakeTransparent();
}
}
public struct udtPixilateColorFind
{
public Color clr;
public int numFound;
}
private void addPixilateColorFound(ref udtPixilateColorFind[] udrPixilateColorFind, Color clrFound)
{
if (udrPixilateColorFind == null)
{
udrPixilateColorFind = new udtPixilateColorFind[1];
udrPixilateColorFind[0] = new udtPixilateColorFind();
udrPixilateColorFind[0].clr = clrFound;
udrPixilateColorFind[0].numFound = 1;
}
else
{
for (int intClrCounter = 0; intClrCounter < udrPixilateColorFind.Length; intClrCounter++)
if (udrPixilateColorFind[intClrCounter].clr == clrFound)
{
udrPixilateColorFind[intClrCounter].numFound++;
return;
}
Array.Resize<udtPixilateColorFind>(ref udrPixilateColorFind, udrPixilateColorFind.Length + 1);
udrPixilateColorFind[udrPixilateColorFind.Length - 1] = new udtPixilateColorFind();
udrPixilateColorFind[udrPixilateColorFind.Length - 1].clr = clrFound;
udrPixilateColorFind[udrPixilateColorFind.Length - 1].numFound = 1;
}
}
void reorderPixilateColorFound(ref udtPixilateColorFind[] udrPixilateColorFind)
{
int intBestFind;
for (int intOuterLoop = 0; intOuterLoop < udrPixilateColorFind.Length - 1; intOuterLoop++)
{
intBestFind = intOuterLoop;
for (int intInnerLoop = intOuterLoop + 1; intInnerLoop < udrPixilateColorFind.Length; intInnerLoop++)
{
if (udrPixilateColorFind[intInnerLoop].numFound > udrPixilateColorFind[intBestFind].numFound)
intBestFind = intInnerLoop;
}
if (intBestFind != intOuterLoop)
{
udtPixilateColorFind udrTemp = udrPixilateColorFind[intOuterLoop];
udrPixilateColorFind[intOuterLoop] = udrPixilateColorFind[intBestFind];
udrPixilateColorFind[intBestFind] = udrTemp;
}
}
}
Bitmap rotate(Bitmap bmpInput, double dblAngleRotation)
{
int intMinSquare = bmpInput.Width > bmpInput.Height ?
3 * bmpInput.Width
: 3 * bmpInput.Height;
Color clrHole = Color.YellowGreen;// some color assumed NOT in the input bmp
Bitmap bmpCopy = new Bitmap(intMinSquare, intMinSquare);
Point ptTL;
Point ptBR;
Point ptCopyCenter = new Point(bmpCopy.Width / 2, bmpCopy.Height / 2);
Point ptOriginalCenter = new Point(bmpInput.Width / 2, bmpInput.Height / 2);
using (Graphics g = Graphics.FromImage(bmpCopy))
{
g.FillRectangle(new SolidBrush(clrHole), new Rectangle(new Point(0, 0), bmpCopy.Size));
ptTL = new Point(ptCopyCenter.X, ptCopyCenter.Y);
ptBR = new Point(ptCopyCenter.X, ptCopyCenter.Y);
for (int intX = 0; intX < bmpInput.Width; intX++)
{
for (int intY = 0; intY < bmpInput.Height; intY++)
{
int intDX = ptOriginalCenter.X - intX;
int intDY = ptOriginalCenter.Y - intY;
classMath.classRadialCoor udrOriginalRad = new classMath.classRadialCoor(classMath.arcTan(intDX, intDY), Math.Sqrt(intDX * intDX + intDY * intDY));
classMath.classRadialCoor udrCopyRad = new classMath.classRadialCoor(udrOriginalRad.angle - dblAngleRotation, udrOriginalRad.radius);
Point ptCopy = new Point((int)(ptCopyCenter.X + udrCopyRad.radius * Math.Cos(udrCopyRad.angle)),
(int)(ptCopyCenter.Y + udrCopyRad.radius * Math.Sin(udrCopyRad.angle)));
try { bmpCopy.SetPixel(ptCopy.X, ptCopy.Y, bmpInput.GetPixel(intX, intY)); }
catch (Exception) { }
// keep track of limits of output image
if (ptCopy.X < ptTL.X)
ptTL.X = ptCopy.X;
if (ptCopy.Y < ptTL.Y)
ptTL.Y = ptCopy.Y;
if (ptCopy.X > ptBR.X)
ptBR.X = ptCopy.X;
if (ptCopy.Y > ptBR.Y)
ptBR.Y = ptCopy.Y;
}
}
}
// write image to output array
Size szOfImage = new Size(ptBR.X - ptTL.X, ptBR.Y - ptTL.Y);
Rectangle recSrc = new Rectangle(ptTL, szOfImage);
Rectangle recDest = new Rectangle(new Point(0, 0), szOfImage);
// fill the blanks missed when rotating image
// scanning x from 0 to width created a problem in the fill-blank
for (int intX = ptTL.X; intX < ptBR.X; intX++)
for (int intY = ptTL.Y; intY < ptBR.Y; intY++)
{
Color clrTest = bmpCopy.GetPixel(intX, intY);
if (clrTest.A == clrHole.A
&& clrTest.R == clrHole.R
&& clrTest.G == clrHole.G
&& clrTest.B == clrHole.B)
{
udtPixilateColorFind[] udrColorFind = new udtPixilateColorFind[0];
if (intX > 0 && intX < bmpCopy.Width - 2 && intY > 0 && intY < bmpCopy.Height - 2)
{
Point ptUp = new Point(intX, intY - 1);
Point ptDown = new Point(intX, intY + 1);
Point ptLeft = new Point(intX - 1, intY);
Point ptRight = new Point(intX + 1, intY);
Point ptUL = new Point(intX - 1, intY - 1);
Point ptUR = new Point(intX + 1, intY - 1);
Point ptDR = new Point(intX + 1, intY + 1);
Point ptDL = new Point(intX - 1, intY + 1);
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptUp.X, ptUp.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptDown.X, ptDown.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptLeft.X, ptLeft.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptRight.X, ptRight.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptDL.X, ptDL.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptDR.X, ptDR.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptUL.X, ptUL.Y));
addPixilateColorFound(ref udrColorFind, bmpCopy.GetPixel(ptUR.X, ptUR.Y));
reorderPixilateColorFound(ref udrColorFind);
if (udrColorFind[0].numFound >= 2)
try { bmpCopy.SetPixel(intX, intY, udrColorFind[0].clr); }
catch (Exception) { }
else
{
int intDX = ptCopyCenter.X - intX;
int intDY = ptCopyCenter.Y - intY;
classMath.classRadialCoor udrOriginalRad = new classMath.classRadialCoor(classMath.arcTan(intDX, intDY), Math.Sqrt(intDX * intDX + intDY * intDY));
classMath.classRadialCoor udrCopyRad = new classMath.classRadialCoor(udrOriginalRad.angle + dblAngleRotation, udrOriginalRad.radius);
Point ptCopy = new Point((int)(ptOriginalCenter.X + udrCopyRad.radius * Math.Cos(udrCopyRad.angle)),
(int)(ptOriginalCenter.Y + udrCopyRad.radius * Math.Sin(udrCopyRad.angle)));
if (ptCopy.X >= 0 && ptCopy.X < bmpCopy.Width && ptCopy.Y >= 0 && ptCopy.Y < bmpCopy.Height)
try { bmpCopy.SetPixel(intX, intY, bmpInput.GetPixel(ptCopy.X, ptCopy.Y)); }
catch (Exception) { }
}
}
}
}
if (recDest.Width < 1)
recDest.Width = 1;
if (recDest.Height < 1)
recDest.Height = 1;
Bitmap bmpTemp = new Bitmap(recDest.Width, recDest.Height);
using (Graphics g = Graphics.FromImage(bmpTemp))
{
g.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, 0, bmpTemp.Width, bmpTemp.Height));
bmpCopy.MakeTransparent(bmpCopy.GetPixel(0, 0));
g.DrawImage(bmpCopy, recDest, recSrc, GraphicsUnit.Pixel);
}
bmpTemp.RotateFlip(RotateFlipType.Rotate180FlipNone);
return bmpTemp;
}
}
}