From: <kro...@us...> - 2007-04-10 11:50:06
|
Revision: 301 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=301&view=rev Author: kroko_koenig Date: 2007-04-10 04:49:50 -0700 (Tue, 10 Apr 2007) Log Message: ----------- Initial Release 0.1 Added Paths: ----------- trunk/Connect4.jpg trunk/Skin/ trunk/Skin/Media/ trunk/Skin/Media/MyConn4Cur.png trunk/Skin/Media/MyConn4Gr.png trunk/Skin/Media/MyConn4Rd.png trunk/Skin/Media/MyConn4Wh.png trunk/Skin/Media/MyConn4Ye.png trunk/Skin/Media/MyConnBack.png trunk/Skin/Media/hover_my connect4.png trunk/Skin/MyConnect4.xml trunk/Skin/Sounds/ trunk/Skin/Sounds/MyConnect4_klick.wav trunk/Source/ trunk/Source/MyConnect4/ trunk/Source/MyConnect4/Engine.cs trunk/Source/MyConnect4/MyConnect4.cs trunk/Source/MyConnect4/MyConnect4.csproj trunk/Source/MyConnect4/Properties/ trunk/Source/MyConnect4/Properties/AssemblyInfo.cs trunk/Source/MyConnect4/State.cs trunk/Source/MyConnect4.sln trunk/Source/MyConnect4.suo trunk/Thumbs.db trunk/readme.txt Added: trunk/Connect4.jpg =================================================================== (Binary files differ) Property changes on: trunk/Connect4.jpg ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/MyConn4Cur.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/MyConn4Cur.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/MyConn4Gr.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/MyConn4Gr.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/MyConn4Rd.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/MyConn4Rd.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/MyConn4Wh.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/MyConn4Wh.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/MyConn4Ye.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/MyConn4Ye.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/MyConnBack.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/MyConnBack.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/Media/hover_my connect4.png =================================================================== (Binary files differ) Property changes on: trunk/Skin/Media/hover_my connect4.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Skin/MyConnect4.xml =================================================================== --- trunk/Skin/MyConnect4.xml (rev 0) +++ trunk/Skin/MyConnect4.xml 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,604 @@ +<window> + <id>22031969</id> + <defaultcontrol>2</defaultcontrol> + <allowoverlay>yes</allowoverlay> + <autohidetopbar>yes</autohidetopbar> + <controls> + <import>common.time.xml</import> + <control> + <description>BackGround</description> + <type>image</type> + <id>10</id> + <posX>0</posX> + <posY>0</posY> + <width>720</width> + <height>576</height> + <texture>background.png</texture> + </control> + <control> + <description>text label</description> + <type>label</type> + <id>11</id> + <posX>60</posX> + <posY>70</posY> + <label>Connect 4</label> + <font>font16</font> + <align>Left</align> + <textcolor>ffffffff</textcolor> + <animation effect="fade" time="150">WindowOpen</animation> + <animation effect="fade" time="150">WindowClose</animation> + </control> + <control> + <type>group</type> + <description>group element</description> + <animation effect="fade" time="150">WindowOpen</animation> + <animation effect="fade" time="150">WindowClose</animation> + <control> + <description>Start</description> + <type>button</type> + <id>2</id> + <posX>60</posX> + <posY>97</posY> + <label>Start</label> + <onleft>2</onleft> + <onright>301</onright> + <onup>7</onup> + <ondown>3</ondown> + </control> + <control> + <description>Mode</description> + <type>button</type> + <id>3</id> + <posX>60</posX> + <posY>131</posY> + <label>Mode: Play vs Player</label> + <onleft>3</onleft> + <onright>3</onright> + <onup>2</onup> + <ondown>4</ondown> + </control> + <control> + <description>Level</description> + <type>button</type> + <id>4</id> + <posX>60</posX> + <posY>165</posY> + <label>Level: Amateur</label> + <onleft>4</onleft> + <onright>4</onright> + <onup>3</onup> + <ondown>7</ondown> + </control> + <control> + <description>text label</description> + <type>label</type> + <id>5</id> + <posX>70</posX> + <posY>205</posY> + <label>#Round</label> + <font>font12</font> + <align>Left</align> + <textcolor>ffffffff</textcolor> + </control> + <control> + <description>text label</description> + <type>label</type> + <id>6</id> + <posX>70</posX> + <posY>240</posY> + <label>#Player</label> + <font>font12</font> + <align>Left</align> + <textcolor>ffffffff</textcolor> + </control> + <control> + <description>Whatsthis</description> + <type>button</type> + <id>7</id> + <posX>60</posX> + <posY>270</posY> + <label>What's this?</label> + <onleft>7</onleft> + <onright>301</onright> + <onup>4</onup> + <ondown>2</ondown> + </control> + </control> + <control> + <description>BackGround Game</description> + <type>image</type> + <id>15</id> + <posX>260</posX> + <posY>120</posY> + <width>440</width> + <height>380</height> + <texture>MyConnBack.png</texture> + <animation effect="fade" time="150">WindowOpen</animation> + <animation effect="fade" time="150">WindowClose</animation> + </control> + <control> + <type>group</type> + <description>group element</description> + <animation effect="fade" time="150">WindowOpen</animation> + <animation effect="fade" time="150">WindowClose</animation> + <control> + <type>image</type> + <id>101</id> + <posX>280</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_1</texture> + </control> + <control> + <type>image</type> + <id>102</id> + <posX>340</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_2</texture> + </control> + <control> + <type>image</type> + <id>103</id> + <posX>400</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_3</texture> + </control> + <control> + <type>image</type> + <id>104</id> + <posX>460</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_4</texture> + </control> + <control> + <type>image</type> + <id>105</id> + <posX>520</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_5</texture> + </control> + <control> + <type>image</type> + <id>106</id> + <posX>580</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_6</texture> + </control> + <control> + <type>image</type> + <id>107</id> + <posX>640</posX> + <posY>140</posY> + <width>40</width> + <height>40</height> + <texture>#Con_1_7</texture> + </control> + + <control> + <type>image</type> + <id>111</id> + <posX>280</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_1</texture> + </control> + <control> + <type>image</type> + <id>112</id> + <posX>340</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_2</texture> + </control> + <control> + <type>image</type> + <id>113</id> + <posX>400</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_3</texture> + </control> + <control> + <type>image</type> + <id>114</id> + <posX>460</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_4</texture> + </control> + <control> + <type>image</type> + <id>115</id> + <posX>520</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_5</texture> + </control> + <control> + <type>image</type> + <id>116</id> + <posX>580</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_6</texture> + </control> + <control> + <type>image</type> + <id>117</id> + <posX>640</posX> + <posY>200</posY> + <width>40</width> + <height>40</height> + <texture>#Con_2_7</texture> + </control> + + <control> + <type>image</type> + <id>121</id> + <posX>280</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_1</texture> + </control> + <control> + <type>image</type> + <id>122</id> + <posX>340</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_2</texture> + </control> + <control> + <type>image</type> + <id>123</id> + <posX>400</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_3</texture> + </control> + <control> + <type>image</type> + <id>124</id> + <posX>460</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_4</texture> + </control> + <control> + <type>image</type> + <id>125</id> + <posX>520</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_5</texture> + </control> + <control> + <type>image</type> + <id>126</id> + <posX>580</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_6</texture> + </control> + <control> + <type>image</type> + <id>127</id> + <posX>640</posX> + <posY>260</posY> + <width>40</width> + <height>40</height> + <texture>#Con_3_7</texture> + </control> + + <control> + <type>image</type> + <id>131</id> + <posX>280</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_1</texture> + </control> + <control> + <type>image</type> + <id>132</id> + <posX>340</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_2</texture> + </control> + <control> + <type>image</type> + <id>133</id> + <posX>400</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_3</texture> + </control> + <control> + <type>image</type> + <id>134</id> + <posX>460</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_4</texture> + </control> + <control> + <type>image</type> + <id>135</id> + <posX>520</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_5</texture> + </control> + <control> + <type>image</type> + <id>136</id> + <posX>580</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_6</texture> + </control> + <control> + <type>image</type> + <id>137</id> + <posX>640</posX> + <posY>320</posY> + <width>40</width> + <height>40</height> + <texture>#Con_4_7</texture> + </control> + + <control> + <type>image</type> + <id>141</id> + <posX>280</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_1</texture> + </control> + <control> + <type>image</type> + <id>142</id> + <posX>340</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_2</texture> + </control> + <control> + <type>image</type> + <id>143</id> + <posX>400</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_3</texture> + </control> + <control> + <type>image</type> + <id>144</id> + <posX>460</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_4</texture> + </control> + <control> + <type>image</type> + <id>145</id> + <posX>520</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_5</texture> + </control> + <control> + <type>image</type> + <id>146</id> + <posX>580</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_6</texture> + </control> + <control> + <type>image</type> + <id>147</id> + <posX>640</posX> + <posY>380</posY> + <width>40</width> + <height>40</height> + <texture>#Con_5_7</texture> + </control> + + <control> + <type>image</type> + <id>151</id> + <posX>280</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_1</texture> + </control> + <control> + <type>image</type> + <id>152</id> + <posX>340</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_2</texture> + </control> + <control> + <type>image</type> + <id>153</id> + <posX>400</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_3</texture> + </control> + <control> + <type>image</type> + <id>154</id> + <posX>460</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_4</texture> + </control> + <control> + <type>image</type> + <id>155</id> + <posX>520</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_5</texture> + </control> + <control> + <type>image</type> + <id>156</id> + <posX>580</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_6</texture> + </control> + <control> + <type>image</type> + <id>157</id> + <posX>640</posX> + <posY>440</posY> + <width>40</width> + <height>40</height> + <texture>#Con_6_7</texture> + </control> + <control> + <description>text label</description> + <type>label</type> + <id>18</id> + <posX>260</posX> + <posY>510</posY> + <label>#Status</label> + <font>font16</font> + <align>Left</align> + <textcolor>ffffffff</textcolor> + </control> + <control> + <description>Pointer 01</description> + <type>button</type> + <id>301</id> + <posX>280</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>2</onleft> + <onright>302</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + <control> + <description>Pointer 02</description> + <type>button</type> + <id>302</id> + <posX>340</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>301</onleft> + <onright>303</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + <control> + <description>Pointer 03</description> + <type>button</type> + <id>303</id> + <posX>400</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>302</onleft> + <onright>304</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + <control> + <description>Pointer 04</description> + <type>button</type> + <id>304</id> + <posX>460</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>303</onleft> + <onright>305</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + <control> + <description>Pointer 05</description> + <type>button</type> + <id>305</id> + <posX>520</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>304</onleft> + <onright>306</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + <control> + <description>Pointer 06</description> + <type>button</type> + <id>306</id> + <posX>580</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>305</onleft> + <onright>307</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + <control> + <description>Pointer 07</description> + <type>button</type> + <id>307</id> + <posX>640</posX> + <posY>70</posY> + <width>40</width> + <height>40</height> + <onleft>306</onleft> + <onright>307</onright> + <textureFocus>MyConn4Cur.png</textureFocus> + </control> + </control> + </controls> +</window> Added: trunk/Skin/Sounds/MyConnect4_klick.wav =================================================================== (Binary files differ) Property changes on: trunk/Skin/Sounds/MyConnect4_klick.wav ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Source/MyConnect4/Engine.cs =================================================================== --- trunk/Source/MyConnect4/Engine.cs (rev 0) +++ trunk/Source/MyConnect4/Engine.cs 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,116 @@ +using System; +using System.Drawing; + +namespace MediaPortal.GUI.MyConnect +{ + /// <summary> + /// Engine class handles the maintenance of player positions + /// on the game board and determines winning sequences of tokens. + /// </summary> + public class Engine + { + private static Random rand = new Random(System.DateTime.Now.Millisecond); + public State state; + + public Engine(int w, int h, int n) + { + state = new State(w, h, n); + } + + public State getState() + { + return state; + } + // drop a 'player' piece in column 'x' + + public Point makeMove(int player, int xPos) + { + int yPos = state.dropPiece(player, xPos); + return (new Point(xPos, yPos)); + } + + // AI algorithm + + public Point computerMove(int player, int level) + { + int bestXPos = -1, goodness = 0, bestWorst = -30000; + int numOfEqual = 0; + + // Simulate a drop in each of the columns + + for (int i = 0; i < state.getW(); i++) + { + State tempState = new State + (state, state.getW(), state.getH(), state.getN()); + + // If column is full, move on to the next column + + if (tempState.dropPiece(player, i) < 0) + continue; + + // If this drop wins the game, then cool + + if (tempState.isWinner(player)) + { + bestWorst = 25000; + bestXPos = i; + } + + // If its not a winner, run evaluate algorithm 'level' times + // to find the best column to drop into. IE level 2 will + // look Columns x 2 drops into the future... etc etc. + + else + goodness = tempState.evaluate(player, level, 1, -30000, + -bestWorst); + + // If this move looks better than the previous move remember it + + if (goodness > bestWorst) + { + bestWorst = goodness; + bestXPos = i; + numOfEqual = 1; + } + + // If two moves are equally good, make a random choice + + if (goodness == bestWorst) + { + numOfEqual++; + if (Math.Abs(rand.NextDouble()) % 10000 < + (10000 / numOfEqual)) + bestXPos = i; + } + } + + // Drop the piece in the best column + + if (bestXPos >= 0) + { + int yPos = state.dropPiece(player, bestXPos); + if (yPos >= 0) + return (new Point(bestXPos, yPos)); + } + return new Point(-1,-1); + } + + // returns the state of the current gameboard + + public int[,] getBoard() + { + return state.board; + } + + public bool isWinner(int player) + { + return state.isWinner(player); + } + + public bool isTie() + { + return state.isTie(); + } + } +} + Added: trunk/Source/MyConnect4/MyConnect4.cs =================================================================== --- trunk/Source/MyConnect4/MyConnect4.cs (rev 0) +++ trunk/Source/MyConnect4/MyConnect4.cs 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,480 @@ +#region Copyright (C) 2005-2007 Team MediaPortal + +/* + * Copyright (C) 2005-2007 Team MediaPortal + * http://www.team-mediaportal.com + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using MediaPortal.GUI.Library; +using MediaPortal.Dialogs; +using MediaPortal.Util; +using MediaPortal.Utils; + +namespace MediaPortal.GUI.MyConnect +{ + public class MyConnect4GUI : GUIWindow , ISetupForm + { + #region SkinControl + [SkinControlAttribute(2)] protected GUIButtonControl BtnStart = null; + [SkinControlAttribute(4)] protected GUIButtonControl BtnLevel = null; + [SkinControlAttribute(3)] protected GUIButtonControl BtnMode = null; + + [SkinControlAttribute(7)] protected GUIButtonControl BtnWhatsThis = null; + #endregion + + #region Private variables + + string Level="Am"; //Choosen level + int AI = 3; + + string Mode = "2p"; //2player + + int Player = 0; + int round = 0; + + int wait = 0; + + private static OnActionHandler ah; + + private System.Windows.Forms.Timer _Game = new System.Windows.Forms.Timer(); + + private Engine gameEngine; + + #endregion + + #region ISetupForm Members + + // Returns the name of the plugin which is shown in the plugin menu + public string PluginName() + { + return "My Connect 4"; + } + + // Returns the description of the plugin is shown in the plugin menu + public string Description() + { + return "Connect 4"; + } + + // Returns the author of the plugin which is shown in the plugin menu + public string Author() + { + return "Mark Koenig (kroko)"; + } + + // show the setup dialog + public void ShowPlugin() + { + MessageBox.Show("Nothing to configure, this is just an example"); + } + + // Indicates whether plugin can be enabled/disabled + public bool CanEnable() + { + return true; + } + + // get ID of windowplugin belonging to this setup + public int GetWindowId() + { + return 22031969; + } + + // Indicates if plugin is enabled by default; + public bool DefaultEnabled() + { + return true; + } + + // indicates if a plugin has its own setup screen + public bool HasSetup() + { + return false; + } + + /// <summary> + /// If the plugin should have its own button on the main menu of MediaPortal then it + /// should return true to this method, otherwise if it should not be on home + /// it should return false + /// </summary> + /// <param name="strButtonText">text the button should have</param> + /// <param name="strButtonImage">image for the button, or empty for default</param> + /// <param name="strButtonImageFocus">image for the button, or empty for default</param> + /// <param name="strPictureImage">subpicture for the button or empty for none</param> + /// <returns>true : plugin needs its own button on home + /// false : plugin does not need its own button on home</returns> + + public bool GetHome(out string strButtonText, out string strButtonImage, out string strButtonImageFocus, out string strPictureImage) + { + strButtonText = PluginName(); + strButtonImage = String.Empty; + strButtonImageFocus = String.Empty; + strPictureImage = "hover_my connect4.png"; + return true; + } + + #endregion + + public override int GetID + { + get + { + return 22031969; + } + set + { + base.GetID = value; + } + } + + public override bool Init() + { + bool result = Load(GUIGraphicsContext.Skin + @"\MyConnect4.xml"); + if (ah == null) ah = new OnActionHandler(OnAction2); + return result; + } + + #region Actions + public override void OnAction(Action action) + { + base.OnAction(action); + } + public void OnAction2(Action action) + { + + if (GUIWindowManager.ActiveWindowEx == (int)GUIWindow.Window.WINDOW_DIALOG_MENU) return; + + //string t = action.wID.ToString(); + //GUIPropertyManager.SetProperty("#Round", t); + + if ((Player == 1) | (Player == 2 && Mode == "2p")) + { + switch (action.wID) + { + case Action.ActionType.ACTION_MOVE_LEFT: + + break; + case Action.ActionType.ACTION_MOVE_RIGHT : + + break; + case Action.ActionType.ACTION_SELECT_ITEM : + + break; + default: + break; + } + } + } + #endregion + + public override bool OnMessage(GUIMessage message) + { + return base.OnMessage(message); + } + + public void Dispose() + { + _Game.Stop(); + _Game.Tick -= new EventHandler(_Game_Tick); + } + + protected override void OnPageLoad() + { + _Game.Interval = 300; + _Game.Tick += new EventHandler(_Game_Tick); + _Game.Start(); + + Player = 0; + Level = "Am"; + Mode = "2p"; + AI = 3; + + GUIPropertyManager.SetProperty("#Status", " "); + GUIControl.SetControlLabel(GetID, BtnLevel.GetID, "Level: Amateur"); + + // Disable level selection + GUIControl.DisableControl(GetID, 4); + + RelButtons(); + + GUIGraphicsContext.OnNewAction -= ah; + GUIGraphicsContext.OnNewAction += ah; + + base.OnPageLoad(); + + this.gameEngine = null; + this.gameEngine = new Engine(7, 6, 4); + + Drawfield (); + + } + + protected override void OnPageDestroy(int new_windowId) + { + _Game.Stop(); + _Game.Tick -= new EventHandler(_Game_Tick); + } + + protected override void OnClicked(int controlId, GUIControl control, MediaPortal.GUI.Library.Action.ActionType actionType) + { + if (control == BtnLevel) + OnBtnLevel(); + if (control == BtnMode) + OnBtnMode(); + if (control == BtnWhatsThis) + OnBtnWhatsThis(); + if (control == BtnStart) + { //start game + + if (Player == 0 && wait==0) + { + Player = 1; + round = 0; + GUIPropertyManager.SetProperty("#Status", " "); + + // Disable start button + GUIControl.DisableControl(GetID, 2); + // Disable level selection + GUIControl.DisableControl(GetID, 3); + // Disable mode selection + GUIControl.DisableControl(GetID, 4); + + this.gameEngine = null; + this.gameEngine = new Engine(7, 6, 4); + + Drawfield(); + + wait = 2; + GUIControl.FocusControl(GetID, 15); + } + } + if ((Player==1)|(Player==2 && Mode=="2p")) + { + + if ((controlId >= 301) && (controlId <= 307)) + { + //which button has clicked ? + int col = controlId - 301; + + PlayerClick(col); + wait = 2; + } + } + base.OnClicked(controlId, control, actionType); + } + + protected override void OnShowContextMenu() + { + base.OnShowContextMenu(); + } + + private void OnBtnLevel() + { //Choose level for the game + if (Player==0) + { + if (Level == "Nor") + { + GUIControl.SetControlLabel(GetID, BtnLevel.GetID, "Level: Professional"); + Level = "Pro"; + AI = 7; + } + else if (Level == "Pro") + { + GUIControl.SetControlLabel(GetID, BtnLevel.GetID, "Level: Amateur"); + Level = "Am"; + AI = 3; + } + else + { + GUIControl.SetControlLabel(GetID, BtnLevel.GetID, "Level: Normal"); + Level = "Nor"; + AI = 5; + } + } + } + + private void OnBtnMode() + { //Choose mode for the game + if (Player == 0) + { + if (Mode == "2p") + { + GUIControl.SetControlLabel(GetID, BtnMode.GetID, "Mode: Play vs Computer"); + Mode = "1p"; + // Enable level selection + GUIControl.EnableControl(GetID, 4); + } + else + { + GUIControl.SetControlLabel(GetID, BtnMode.GetID, "Mode: Play vs Player"); + Mode = "2p"; + // Disable level selection + GUIControl.DisableControl(GetID, 4); + } + } + } + + private void OnBtnWhatsThis() + { + GUIDialogText dlg = (GUIDialogText)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_TEXT); + dlg.SetHeading("What's Connect 4 (Vier gewinnt)"); + dlg.SetText("Connect 4 is a game where your object is to get 4 tokens in a row.\n" + + "This could be vertically, horizontal or diagonally.\n\n" + + "Gameboard design by Mikael S\xF6derstr\xF6m.\n\n" + + "AI code has been taken from http://www.Planet-Source-Code.com\n\n" + + "Good luck\nkroko"); + dlg.DoModal(GetID); + } + + private void Drawfield() + { // draw all fields + + int[,] Myboard = gameEngine.getBoard(); + + for (int i = 0; i < 7; i++) + { + for (int j = 0; j < 6; j++) + { + string prop = "#Con_" + (6-j) + "_" + (i+1); + + if (Myboard[i, j] == 2) + GUIPropertyManager.SetProperty(prop, "MyConn4Wh.png"); + if (Myboard[i, j] == 0) + GUIPropertyManager.SetProperty(prop, "MyConn4Ye.png"); + if (Myboard[i, j] == 1) + GUIPropertyManager.SetProperty(prop, "MyConn4Rd.png"); + if (Myboard[i, j] > 2) + GUIPropertyManager.SetProperty(prop, "MyConn4Gr.png"); + } + } + } + + private void PlayerClick(int droppos) + { + Point pos = gameEngine.makeMove(Player - 1, droppos); + if (pos.Y >= 0) + { + round++; + Drawfield(); + MediaPortal.Util.Utils.PlaySound("MyConnect4_klick.wav", false, true); + + + if (gameEngine.isWinner(Player - 1) == true) + { + int tmp = Player; + GUIPropertyManager.SetProperty("#Status", "Player " + tmp + " wins the game !"); + Player = 0; + RelButtons(); + gameEngine.getState().flashit(3); + Drawfield(); + } + if (gameEngine.isTie() == true) + { + GUIPropertyManager.SetProperty("#Status", "Nobody wins the game ! Its a draw !"); + Player = 0; + RelButtons(); + GUIDialogOK dlg = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); + } + NextPlayer(); + } + + Drawfield(); + } + + private void NextPlayer() + { + if (Player != 0) + { + Player = Player + 1; + if (Player > 2) + Player = 1; + } + } + + private void RelButtons() + { + // Enable start button + GUIControl.EnableControl(GetID, 2); + // Enable mode selection + GUIControl.EnableControl(GetID, 3); + if (Mode == "1p") // Enable level selection + GUIControl.EnableControl(GetID, 4); + // Enable What this + GUIControl.EnableControl(GetID, 7); + + GUIControl.FocusControl(GetID, 2); + } + + void _Game_Tick(object sender, EventArgs e) + { + //display status of the game + if (Player == 0) + GUIPropertyManager.SetProperty("#Player", "GAME OVER"); + if (Player == 1) + GUIPropertyManager.SetProperty("#Player", "PLAYER 1"); + if (Player == 2) + GUIPropertyManager.SetProperty("#Player", "PLAYER 2"); + GUIPropertyManager.SetProperty("#Round", "Round: " + round ); + //wait time + if (wait > 0) + { + wait = wait - 1; + } + + if (Player == 2 && Mode == "1p" && wait==0) + { + Point pos = gameEngine.computerMove(1, AI); + if (pos.Y >= 0) + { + wait = 2; + round++; + Drawfield(); + MediaPortal.Util.Utils.PlaySound("MyConnect4_klick.wav", false, true); + + + if (gameEngine.isWinner(Player - 1) == true) + { + GUIPropertyManager.SetProperty("#Status", "Player 2 wins the game !"); + gameEngine.getState().flashit(3); + Drawfield(); + Player = 0; + RelButtons(); + } + if (gameEngine.isTie() == true) + { + GUIPropertyManager.SetProperty("#Status", "Nobody wins the game ! Its a draw !"); + Player = 0; + RelButtons(); + } + NextPlayer(); + } + Drawfield(); + + } + } + + } +} Added: trunk/Source/MyConnect4/MyConnect4.csproj =================================================================== --- trunk/Source/MyConnect4/MyConnect4.csproj (rev 0) +++ trunk/Source/MyConnect4/MyConnect4.csproj 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,54 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{7D1DBAFA-199A-47D9-A19C-9FCBA4B3F1EA}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>MyConnect4</RootNamespace> + <AssemblyName>MyConnect4</AssemblyName> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Core, Version=1.0.2593.1921, Culture=neutral, processorArchitecture=MSIL" /> + <Reference Include="Dialogs, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL" /> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Drawing" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + <Reference Include="Utils, Version=1.0.2593.1896, Culture=neutral, processorArchitecture=MSIL" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Engine.cs" /> + <Compile Include="MyConnect4.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="State.cs" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: trunk/Source/MyConnect4/Properties/AssemblyInfo.cs =================================================================== --- trunk/Source/MyConnect4/Properties/AssemblyInfo.cs (rev 0) +++ trunk/Source/MyConnect4/Properties/AssemblyInfo.cs 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("MyConnect4")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MyConnect4")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("9c36c885-c7f8-460a-a4bf-4b1893faf9bf")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Revisions- und Buildnummern +// übernehmen, indem Sie "*" eingeben: +[assembly: AssemblyVersion("0.1.0.0")] +[assembly: AssemblyFileVersion("0.1.0.0")] Added: trunk/Source/MyConnect4/State.cs =================================================================== --- trunk/Source/MyConnect4/State.cs (rev 0) +++ trunk/Source/MyConnect4/State.cs 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,313 @@ +using System; + +namespace MediaPortal.GUI.MyConnect +{ + /// <summary> + /// Monitors The State of a Game Board of width [columns] w, height [rows] h, + /// and maintains each possible winning combination of places on the + /// game board. + /// </summary> + + public class State + { + + private int winPlaces = 69, maxPieces = 42, Empty = 2; + private static bool[,,] map; + public int[,] board; + private int[,] score; + private int numPieces; + private int w = 7, h = 6, n = 4; + + public int getW() + { + return w; + } + public int getH() + { + return h; + } + public int getN() + { + return n; + } + + public State(int width, int height, int towin) + { + this.w = width; + this.h = height; + this.n = towin; + + winPlaces = (h*(w-n+1))+(w*(h-n+1))+(2*((h-n+1)*(w-n+1))); + maxPieces = w*h; + this.board = new int[w,h]; + this.score = new int[Empty,winPlaces]; + int i, j, k, count = 0; + + if (map == null) + { + map = new bool[w,h,winPlaces]; + for (i = 0; i < w; i++) + for (j = 0; j < h; j++) + for (k = 0; k < winPlaces; k++) + map[i,j,k] = false; + + // Set the horizontal win positions + + for (i = 0; i < h; i++) + for (j = 0; j < (w - n) + 1; j++) + { + for (k = 0; k < n; k++) + map[j + k,i,count] = true; + count++; + } + + // Set the vertical win positions + + for (i = 0; i < w; i++) + for (j = 0; j < (h - n) + 1; j++) + { + for (k = 0; k < n; k++) + map[i,j + k,count] = true; + count++; + } + + // Set the forward diagonal win positions + + for (i = 0; i < (h - n) + 1; i++) //(i = 0; i < h - n; i++) + for (j = 0; j < (w - n) + 1; j++) + { + for (k = 0; k < n; k++) + map[j + k,i + k,count] = true; + count++; + } + + // Set the backward diagonal win positions + /// + /// NOTE: the following nested loop is buggy... + /// one of the limit calculations is wrong... + /// result is that various combinations of + /// column x row sizes will cause either an exception + /// or will let a winning sequence be missed. + /// + + for (i = 0; i < (h - n) + 1; i++)//(i = 0; i < h - n; i++) + for (j = w - 1; j >= w - n; j--) + { // ;j >= w - n + 1; + for (k = 0; k < n; k++) + map[j - k,i + k,count] = true; + count++; + } + } + + // Initialize the board + + for (i = 0; i < w; i++) + for (j = 0; j < h; j++) + board[i,j] = Empty; + + // Initialize the scores + + for (i = 0; i < 2; i++) + for (j = 0; j < winPlaces; j++) + score[i,j] = 1; + + numPieces = 0; + + } + public State(State state, int width, int height, int towin) + { + this.w = width; + this.h = height; + this.n = towin; + + // work out the winning combinations on the given boardsize + // this is the number of times we can fit a unique line of + // length(n) in a board of height(h) by width(w) + + winPlaces = (h*(w-n+1))+(w*(h-n+1))+(2*((h-n+1)*(w-n+1))); + + // work out how many pieces will fill the board + + maxPieces = w*h; + + // create the board with the given height and width + + this.board = new int[w,h]; + + // create an array to track player points for each move + + this.score = new int[Empty,winPlaces]; + + // Copy the current board onto this one + + for (int i = 0; i < w; i++) + for (int j = 0; j < h; j++) + board[i,j] = state.board[i,j]; + + // Copy the current scores onto this one + + for (int i = 0; i < 2; i++) + for (int j = 0; j < winPlaces; j++) + score[i,j] = state.score[i,j]; + numPieces = state.numPieces; + } + + // winscore = 2^n IE. 4 balls in a row to win is 2^4 = 16 + + public bool isWinner(int player) + { + double winscore = Math.Pow(2, n); + for (int i = 0; i < winPlaces; i++) + if (score[player,i] == winscore) + return true; + return false; + } + + public bool isTie() + { + return (numPieces == maxPieces); + } + + public int dropPiece(int player, int xPos) + { + int yPos = 0; + + // drop from the top to the first empty slot + // ******** access an animation simulation routine + // through here... + + while ((board[xPos,yPos] != Empty) && (++yPos < h)); + if (yPos == h) // if the column is full + return -1; + + // otherwise the move is OK + // record the player now in that position + + board[xPos,yPos] = player; + numPieces++; + + // check the game state... + + updateScore(player, xPos, yPos); + return yPos; + } + + // evaluate continues Connect4Engine.computerMove method + // with alternate players + + public int evaluate(int player, int level, int depth, int alpha, int beta) + { + int goodness, best, maxab = alpha; + if (level != depth) + { + best = -30000; + + // drop into each column + + for(int i = 0; i < w; i++) + { + State tempState = new State(this, w, h, n); + + // if the column is full go to the next column... + + if (tempState.dropPiece(getOtherPlayer(player), i) < 0) + continue; + + // if the drop is a winner this is as far as we go in this + // look forward... + + if (tempState.isWinner(getOtherPlayer(player))) + goodness = 25000 - depth; + else + + // otherwise play the other players turn and see what they + // can do. + + goodness = tempState.evaluate(getOtherPlayer(player), + level, depth + 1, -beta, -maxab); + + // if their turn was better than ours, remember it. + + if (goodness > best) + { + best = goodness; + + // if this is the best so far remember it. + + if (best > maxab) + maxab = best; + } + + // logic error occurred - passed int limit + // simulates human error :) + + if (best > beta) + break; + } + return -best; + } + return (calcScore(player) - calcScore(getOtherPlayer(player))); + } + + // total a players score + + private int calcScore(int player) + { + int s = 0; + for (int i = 0; i < winPlaces; i++) + s += score[player,i]; + return s; + } + + // update the score array. If a map array coordinate is true, + // find which player is in that square and add the player number + // to the scoreboard. + + private void updateScore(int player, int x, int y) + { + for (int i = 0; i < winPlaces; i++) + if (map[x,y,i]) + { + score[player,i] <<= 1; + score[getOtherPlayer(player),i] = 0; + } + } + + // swap player focus + + private int getOtherPlayer(int player) + { + return (1 - player); + } + + // replaces game winner with temp value for animation routine + + public int flashit(int lux) + { + double winner = Math.Pow(2, n); + int i, j, k = 0; + int winplayer = 1; + for(i = 0; i < 2; i++) + { + for(j = 0; j < winPlaces; j++) + { + if( score[i,j] == (int)winner ) + k = j; + } + } + for(i = 0; i < w; i ++) + { + for(j = 0; j < h; j++) + { + if (map[i,j,k] == true) + { + winplayer = board[i,j]; + board[i,j] = lux; + } + } + } + return winplayer; + } + } +} + Added: trunk/Source/MyConnect4.sln =================================================================== --- trunk/Source/MyConnect4.sln (rev 0) +++ trunk/Source/MyConnect4.sln 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyConnect4", "MyConnect4\MyConnect4.csproj", "{7D1DBAFA-199A-47D9-A19C-9FCBA4B3F1EA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7D1DBAFA-199A-47D9-A19C-9FCBA4B3F1EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D1DBAFA-199A-47D9-A19C-9FCBA4B3F1EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D1DBAFA-199A-47D9-A19C-9FCBA4B3F1EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D1DBAFA-199A-47D9-A19C-9FCBA4B3F1EA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal Added: trunk/Source/MyConnect4.suo =================================================================== (Binary files differ) Property changes on: trunk/Source/MyConnect4.suo ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Thumbs.db =================================================================== (Binary files differ) Property changes on: trunk/Thumbs.db ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/readme.txt =================================================================== --- trunk/readme.txt (rev 0) +++ trunk/readme.txt 2007-04-10 11:49:50 UTC (rev 301) @@ -0,0 +1,21 @@ +Visit the forum +http://forum.team-mediaportal.com/new_game_connect_4_vier_gewinnt-t20442.html + +Connect 4 (Vier gewinnt) +------------------------ +-Initial release +-1 and 2 player support +-Gameboard design by Mikael S\xF6derstr\xF6m. + +This nice game from MB as a MP version. You can play with +- the mouse +- remote left/right and OK + +Copy the plugin and skin files into your favorite skin folder. +I had to adjust my remote a little in the setup. It was to sensitve. + + +Have fun. + +Greetz +kroko \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |