private unsafe void aiRunner() { // init game state gs = new GameState(); gs.AutomaticLevelChange = false; gs.Replay = true; gs.StartPlay(); if (v != null) { v.SetGameState(gs); } if (selectedAI != null && selectedAI.Type != null) { controller = (BasePacman)selectedAI.Type.GetConstructor(new Type[] { }).Invoke(new object[] { }); } else { controller = null; } initializePosInfos(); scores = new List <int>(); // load resources System.Reflection.Assembly thisExe = System.Reflection.Assembly.GetExecutingAssembly(); System.IO.Stream file = thisExe.GetManifestResourceStream("MsPacmanController.Resources.screenplayer.png"); sprites = (Bitmap)Bitmap.FromStream(file); unsafe { spritesRgbWidth = sprites.Width; spritesRgbHeight = sprites.Height; BitmapData spritesBitmapData = sprites.LockBits(new Rectangle(0, 0, sprites.Width, sprites.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb); IntPtr spritesPtr = spritesBitmapData.Scan0; spritesRgbValues = new int[sprites.Width * sprites.Height]; Marshal.Copy(spritesPtr, spritesRgbValues, 0, sprites.Width * sprites.Height); sprites.UnlockBits(spritesBitmapData); for (int i = 0; i < spritesRgbValues.Length; i++) { spritesRgbValues[i] = (int)(((uint)spritesRgbValues[i]) - 0xFF000000); } } // init for scoreshot scoreShot = new Bitmap(48, 7); scoreGfx = Graphics.FromImage((Image)scoreShot); spriteSums = new int[10]; for (int i = 0; i < 10; i++) { int sum = 0; for (int y = 0; y < 7; y++) { sum += (getSpriteColor(6 + i * 8, 98 + y) << y); } spriteSums[i] = sum; //Console.WriteLine(i + " = " + sum); } // runningPacman = true; while (true) { watch.Start(); // get window info WINDOWINFO info = Comm.GetWindowInfoEasy(msPacmanProcess.MainWindowHandle); if (info.dwWindowStatus == 0) { break; } // capture frame bitmap = (Bitmap)NativeMethods.GetDesktopBitmap(info.rcClient.Left, info.rcClient.Top, width, height, bitmap); unsafe { BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); IntPtr ptr = bitmapData.Scan0; Marshal.Copy(ptr, colorValues, 0, size); // before we eliminate the maze :) currentMaze = findMaze(); // subtract red maze switch (currentMaze) { case Maze.Red: subtractMaze(mazeRedEmpty); break; case Maze.LightBlue: subtractMaze(mazeLightblueEmpty); break; case Maze.Brown: subtractMaze(mazeBrownEmpty); break; case Maze.DarkBlue: throw new ApplicationException("DarkBlue maze not implemented (do it yourself you lazy f**k ;) )"); default: subtractMaze(mazeRedEmpty); break; // to eliminate alpha values } // Copy the RGB values back to the bitmap //Marshal.Copy(colorValues, 0, ptr, size); bitmap.UnlockBits(bitmapData); NativeMethods.DeleteObject(ptr); } // remove alpha /*for( int i = 0; i < colorValues.Length; i++ ) { * colorValues[i] = (int)(((uint)colorValues[i]) - 0xFF000000); * }*/ // update framerate if (runningAvg.Count > 8) { runningAvg.Dequeue(); } if (runningAvg.Count != 0) { msPerFrame = 0; foreach (long ms in runningAvg) { msPerFrame += (int)ms; } msPerFrame /= runningAvg.Count; } // find scores int newScore = findScore(); if (newScore % 10 != 0) { newScore = -1; } if (newScore < score) { scoreToAddToAvg = score; if (score > (int)settings["Highscore"]) { settings["Highscore"] = score; settings.Save(); } } if (scoreToAddToAvg != -1 && score < 400 && score > 0) { scores.Add(scoreToAddToAvg); if (controller != null) { using (StreamWriter sw = new StreamWriter(File.Open("scores.txt", FileMode.Append))) { sw.WriteLine(controller.Name + "\t\t" + scoreToAddToAvg); } } scoreToAddToAvg = -1; } score = newScore; if (score != -1) { determineState(); if (currentState == State.StartScreen) { GC.Collect(); Comm.AddCredit(); Comm.StartGame(); } // play play(); // update entered/not entered foreach (Ghost ghost in gs.Ghosts) { if (ghost.Node.X >= 10 && ghost.Node.X <= 17 && ghost.Node.Y >= 12 && ghost.Node.Y <= 16) { ghost.SetEntered(false); } else if (!ghost.Node.Walkable) { ghost.SetEntered(false); } else { ghost.SetEntered(true); } } if (controller != null) { // control direction = controller.Think(gs); //Console.WriteLine(direction); if (direction == Direction.Stall) { if (stall == Direction.None) { direction = gs.Pacman.InverseDirection(gs.Pacman.Direction); stall = direction; } else { direction = gs.Pacman.InverseDirection(stall); stall = direction; } } else { stall = Direction.None; } Comm.SendKey(direction); } } else { GC.Collect(); currentState = State.BetweenLevels; } // update status this.BeginInvoke(updateMethod); watch.Stop(); // update running avg runningAvg.Enqueue(watch.ElapsedMilliseconds); // reset watch.Reset(); Thread.Sleep(30); } runningPacman = false; this.BeginInvoke(updateMethod); }
private void buttonInit_Click(object sender, EventArgs e) { reset(); // 32 bit color if (Screen.PrimaryScreen.BitsPerPixel != 32) { failure(pictureInit32Bit, "The screen must be set to 32 bit colors"); return; } else { success(pictureInit32Bit); } // ms. pacman is loaded // find process Process[] processes = Process.GetProcesses(); foreach (Process p in processes) { if (p.MainWindowTitle.StartsWith("Ms. Pac-Man")) { //if( p.MainWindowTitle.StartsWith("WebPacMan") ) { msPacmanProcess = p; } } // set as foreground window try { Comm.ShowWindow(msPacmanProcess.MainWindowHandle, (int)WindowShowStyle.Restore); Comm.SetWindowPos(msPacmanProcess.MainWindowHandle, (IntPtr)Comm.HWND_TOP, this.Left + this.Width, this.Top, 0, 0, 0); success(pictureInitFoundGame); } catch { failure(pictureInitFoundGame, "Please make sure Microsoft Ms. Pacman is running"); return; } // entire window: 234, 344 // working area: 224, 288 // locate game area try{ WINDOWINFO info = Comm.GetWindowInfoEasy(msPacmanProcess.MainWindowHandle); gameRect = new Rectangle(info.rcClient.Left, info.rcClient.Top, info.rcClient.Width, info.rcClient.Height); success(pictureInitLocated); } catch (Exception ex) { failure(pictureInitLocated, ex.Message); } // start window if (checkBoxVisualizer.Checked && vThread == null) // seeing problems? remember to debug with this first! { vThread = new System.Threading.Thread(delegate() { v = new Visualizer(); v.Location = new Point(this.Right, this.Top + this.Height); v.StartPosition = FormStartPosition.Manual; try { System.Windows.Forms.Application.Run(v); } catch { } }); vThread.Start(); System.Threading.Thread.Sleep(2000); } // success buttonStart.Enabled = true; labelInitialized.Visible = true; // autoplay if (checkBoxAutoPlay.Checked) { buttonStart_Click(null, null); } else { this.BringToFront(); } }