You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
7.0 KiB
C#

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<Tuple<int, int>> mPossiblePlaces = new List<Tuple<int, int>>();
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<int, int>(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();
}
}
}