using IntelOrca.Launchpad; using Midi; using System; using System.Collections.Generic; namespace IntelOrca.LaunchpadTests { class Reversi { private Random mRandom = new Random(); private LaunchpadDevice mLaunchpadDevice; private int[,] mGrid = new int[8, 8]; private int mPlayerTurn = 1; private int mPlayerWinning = 0; private int mConfirmTime; private bool mForceDraw; private int mGameState = 0; private bool mShowPossibleMoves = true; private bool mSolo = false; private int mFlashCounter = 0; private List> mPossiblePlaces = new List>(); OutputDevice mOutputDevice; public Reversi(LaunchpadDevice device) { mLaunchpadDevice = device; mLaunchpadDevice.DoubleBuffered = false; mLaunchpadDevice.ButtonPressed += mLaunchpadDevice_ButtonPressed; mOutputDevice = OutputDevice.InstalledDevices[0]; mOutputDevice.Open(); Restart(); } private void mLaunchpadDevice_ButtonPressed(object sender, ButtonPressEventArgs e) { if (e.Type == ButtonType.Grid) { if (CanPlaceAt(e.X, e.Y)) PlaceAt(e.X, e.Y); } else if (e.Type == ButtonType.Side) { if (e.SidebarButton == SideButton.TrackOn) { mShowPossibleMoves = !mShowPossibleMoves; mForceDraw = true; } else if (e.SidebarButton == SideButton.Solo) { mSolo = !mSolo; } } else if (e.Type == ButtonType.Toolbar) { if (e.ToolbarButton == ToolbarButton.Session) { if (mConfirmTime > 0) { Restart(); mConfirmTime = 0; } else { mConfirmTime = 1000; } } } } private void Restart() { for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) mGrid[x, y] = 0; mGrid[3, 3] = 1; mGrid[4, 3] = 2; mGrid[3, 4] = 2; mGrid[4, 4] = 1; mGameState = 0; SetPlayerGo(1); mOutputDevice.SendPercussion(Percussion.LongWhistle, 127); } private bool CanPlaceAt(int x, int y) { if (mGrid[x, y] != 0) return false; for (int dy = -1; dy <= 1; dy++) for (int dx = -1; dx <= 1; dx++) if (CheckDirection(x, y, dx, dy)) return true; return false; } private bool CheckDirection(int x, int y, int dx, int dy, int state = 0) { x += dx; y += dy; if (!InBounds(x, y)) return false; if (state == 0) { if (mGrid[x, y] == 0 || mGrid[x, y] == mPlayerTurn) return false; return CheckDirection(x, y, dx, dy, 1); } else if (state == 1) { if (mGrid[x, y] == 0) return false; if (mGrid[x, y] == mPlayerTurn) return true; return CheckDirection(x, y, dx, dy, 1); } return false; } private bool InBounds(int x, int y) { return (x >= 0 && y >= 0 && x < 8 && y < 8); } private void PlaceAt(int x, int y) { if (mPlayerTurn == 1) mOutputDevice.SendPercussion(Percussion.SnareDrum1, 127); else if (mPlayerTurn == 2) mOutputDevice.SendPercussion(Percussion.SnareDrum2, 127); for (int dy = -1; dy <= 1; dy++) for (int dx = -1; dx <= 1; dx++) if (CheckDirection(x, y, dx, dy)) SwapDirection(x, y, dx, dy); mGrid[x, y] = mPlayerTurn; SetPlayerGo((mPlayerTurn == 1 ? 2 : 1)); } private void SwapDirection(int x, int y, int dx, int dy) { x += dx; y += dy; if (mGrid[x, y] != mPlayerTurn) { mGrid[x, y] = mPlayerTurn; SwapDirection(x, y, dx, dy); } } private void UpdatePossiblePlaces() { mPossiblePlaces.Clear(); for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) if (CanPlaceAt(x, y)) mPossiblePlaces.Add(new Tuple(x, y)); } private void SetPlayerGo(int n) { mPlayerTurn = n; UpdatePossiblePlaces(); if (mPossiblePlaces.Count == 0) { mPlayerTurn = (mPlayerTurn == 1 ? 2 : 1); UpdatePossiblePlaces(); if (mPossiblePlaces.Count == 0) { mGameState = 1; mConfirmTime = int.MaxValue; mOutputDevice.SendPercussion(Percussion.CrashCymbal1, 127); } } mPlayerWinning = GetWinner(); if (mPossiblePlaces.Count > 0 && mSolo && mPlayerTurn == 2) { int p = mRandom.Next(0, mPossiblePlaces.Count); PlaceAt(mPossiblePlaces[p].Item1, mPossiblePlaces[p].Item2); } mForceDraw = true; } private int GetWinner() { int p1 = 0, p2 = 0; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (mGrid[x, y] == 1) p1++; else if (mGrid[x, y] == 2) p2++; } } if (p1 > p2) return 1; else if (p2 > p1) return 2; else return 0; } public void Run() { long last_tick = Environment.TickCount; long delay = 1; long duration = 0; while (true) { delay = (int)(1000.0 / 60.0); duration = Environment.TickCount - last_tick; if (duration < delay) { if (mForceDraw) { Draw(); mForceDraw = false; } continue; } last_tick = Environment.TickCount; mConfirmTime = Math.Max(0, mConfirmTime - (int)duration); mFlashCounter = (mFlashCounter + 1) % 20; Draw(); } } private void Draw() { ButtonBrightness[,] redgrid = new ButtonBrightness[8, 8]; ButtonBrightness[,] greengrid = new ButtonBrightness[8, 8]; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (mGrid[x, y] == 1) { redgrid[x, y] = ButtonBrightness.Full; } else if (mGrid[x, y] == 2) { greengrid[x, y] = ButtonBrightness.Full; } else if (mShowPossibleMoves && mFlashCounter < 10) { if (mPossiblePlaces.Exists(p => p.Item1 == x && p.Item2 == y)) { redgrid[x, y] = ButtonBrightness.Low; greengrid[x, y] = ButtonBrightness.Low; } } } } for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) mLaunchpadDevice[x, y].SetBrightness(redgrid[x, y], greengrid[x, y]); if (mPlayerTurn == 1) { mLaunchpadDevice.GetButton(ToolbarButton.User1).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off); mLaunchpadDevice.GetButton(ToolbarButton.User2).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off); } else if (mPlayerTurn == 2) { mLaunchpadDevice.GetButton(ToolbarButton.User1).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off); mLaunchpadDevice.GetButton(ToolbarButton.User2).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full); } if (mPlayerWinning == 1) { mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Full, ButtonBrightness.Off); } else if (mPlayerWinning == 2) { mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Full); } else { mLaunchpadDevice.GetButton(ToolbarButton.Mixer).SetBrightness(ButtonBrightness.Off, ButtonBrightness.Off); } if (mShowPossibleMoves) mLaunchpadDevice.GetButton(SideButton.TrackOn).TurnOnLight(); else mLaunchpadDevice.GetButton(SideButton.TrackOn).TurnOffLight(); if (mConfirmTime > 0) mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOnLight(); else mLaunchpadDevice.GetButton(ToolbarButton.Session).TurnOffLight(); if (mSolo) mLaunchpadDevice.GetButton(SideButton.Solo).TurnOnLight(); else mLaunchpadDevice.GetButton(SideButton.Solo).TurnOffLight(); } } }