プログラム長いorz
プログラム見にくいorz
AIとかないorz
オブジェクト指向じゃないorz
Siv3D二日目
まだまだ勉強しないとな((o(´∀`)o))ワクワク
Main.cpp
#include <Siv3D.hpp>
namespace rev {
class Color {
int color;
public:
static const auto EMPTY = 0;
static const auto WHITE = 1;
static const auto BLACK = 2;
static const auto WALL = 3;
Color() { set(EMPTY); }
Color(int color) { set(color); }
int get() { return color; }
Color& set(int color) { this->color = color;; return *this; }
Color c(int color) { return Color(color); }
Color& reversi() { color = 3 - color; return *this; }
Color getReversi() { return Color(3 - color); }
auto drawColor() { return drawColor(color); }
static s3d::Color drawColor(Color color) {
return color.get() == WHITE ? Palette::White : Palette::Black;
}
};
class Tile {
public:
static const auto SIZE = 32;
Color color;
void draw(Vec2 pos) {
if (color.get() == Color::WALL) return;
Rect(pos.x,pos.y, SIZE).drawFrame(3,0,Palette::Black);
if (color.get() == Color::EMPTY) return;
Circle(pos.x + SIZE / 2, pos.y + SIZE / 2, SIZE / 2.7).draw(color.drawColor());
}
bool click(Vec2 pos) {
return Circle(pos.x + SIZE / 2, pos.y + SIZE / 2, SIZE / 2.7).leftPressed;
}
bool mouseOver(Vec2 pos) {
return Circle(pos.x + SIZE / 2, pos.y + SIZE / 2, SIZE / 2.7).mouseOver;
}
bool draw(Vec2 pos, s3d::Color color,int size = SIZE) {
Rect(pos.x, pos.y, size).drawFrame(3, 0, Palette::Black);
Circle(pos.x + size / 2, pos.y + size / 2, size / 2.7).draw(color);
return Circle(pos.x + size / 2, pos.y + size / 2, size / 2.7).leftPressed;
}
};
class Board {
Array<Tile> tiles;
public:
static const auto SIZE_X = 10;
static const auto SIZE_Y = 10;
static const auto SIZE = SIZE_X * SIZE_Y;
Board() {
Color c;
Array<int,SIZE> tmpTiles = {
3,3,3,3,3,3,3,3,3,3,
3,0,0,0,0,0,0,0,0,3,
3,0,0,0,0,0,0,0,0,3,
3,0,0,0,0,0,0,0,0,3,
3,0,0,0,1,2,0,0,0,3,
3,0,0,0,2,1,0,0,0,3,
3,0,0,0,0,0,0,0,0,3,
3,0,0,0,0,0,0,0,0,3,
3,0,0,0,0,0,0,0,0,3,
3,3,3,3,3,3,3,3,3,3,
};
tiles.clear();
for (int color : tmpTiles) {
Tile tile;
tile.color.set(color);
tiles.push_back(tile);
}
}
Tile &getTile(Vec2 pos) { return tiles[pos.y * SIZE_X + pos.x]; }
void draw() {
for (auto y = 0;y < SIZE_Y;y++) {
for (auto x = 0;x < SIZE_X;x++) {
getTile(Vec2(x, y)).draw({ x * Tile::SIZE,y * Tile::SIZE });
}
}
}
void drawMovableTile(Color c) {
auto mp = getMovablePoints(c);
for (auto p : mp) {
getTile(p).draw(p*Tile::SIZE, c.drawColor().setAlpha(128));
if (getTile(p).mouseOver(p*Tile::SIZE)) getTile(p).draw(p*Tile::SIZE, c.drawColor().setAlpha(64));
}
}
Vec2 clickTile() {
for (auto y = 0;y < SIZE_Y;y++) {
for (auto x = 0;x < SIZE_X;x++) {
if (getTile(Vec2(x, y)).click({ x * Tile::SIZE,y * Tile::SIZE })) return{ x,y };
}
}
return{ -1,-1 };
}
bool move(Vec2 pos, Color c, bool back = false) {
Array<bool> results;
results.push_back(angleMove(pos, { 1,0 }, c, back));
results.push_back(angleMove(pos, { -1,0 }, c, back));
results.push_back(angleMove(pos, { 0,1 }, c, back));
results.push_back(angleMove(pos, { 0,-1 }, c, back));
results.push_back(angleMove(pos, { 1,1 }, c, back));
results.push_back(angleMove(pos, { -1,1 }, c, back));
results.push_back(angleMove(pos, { 1,-1 }, c, back));
results.push_back(angleMove(pos, { -1,-1 }, c, back));
for (auto result : results) { if (result) { back ? getTile(pos).color.set(c.get()) : 0; return true; } }
return false;
}
bool angleMove(Vec2 start, Vec2 angle, Color c, bool back = false) {
if (back) { if (!angleMove(start, angle, c)) { return false; } }
if (getTile(start).color.get() != Color::EMPTY) return false;
if (getTile(start + angle).color.get() != c.getReversi().get()) return false;
Vec2 pos = start + angle;
while (getTile(pos).color.get() == c.getReversi().get())
{
if (back) getTile(pos).color.reversi();
pos += angle;
}
if (getTile(pos).color.get() != c.get()) return false;
return true;
}
Array<Vec2> getMovablePoints(Color c) {
Array<Vec2> result;
for (auto y = 0;y < SIZE_Y;y++) {
for (auto x = 0;x < SIZE_X;x++) {
if (move({ x,y }, c)) result.push_back({x,y});
}
}
return result;
}
bool tileSearch(Color c) {
for (auto t : tiles) {
if (t.color.get() == c.get()) return true;
}
return false;
}
int tileNum(Color c) {
auto result = 0;
for (auto t : tiles) {
if (t.color.get() == c.get()) result++;
}
return result;
}
};
class Reversi {
Board board;
GUI pass;
GUI result;
public:
Color turn;
Reversi() {
Graphics::SetBackground(Palette::Green);
Window::SetTitle(L"Reversi");
turn = turn.BLACK;
GUIStyle style = GUIStyle::Default;
style.width = 200;
pass = GUI(style);
pass.setTitle(L"あなたは置けません。");
pass.add(L"OK", GUIButton::Create(L"パスする"));
pass.setCenter(Window::Center());
pass.hide();
result = GUI(GUIStyle::Default);
result.setTitle(L"ゲーム終了");
result.add(L"result", GUIText::Create(L"", 300));
result.add(L"play", GUIButton::Create(L"もう一度プレイ"));
result.add(L"exit", GUIButton::Create(L"終了"));
result.hide();
}
void main() {
while (System::Update()) {
ClearPrint();
board.draw();
board.drawMovableTile(turn);
Vec2 click = board.clickTile();
click.x != -1 ? board.move(click, turn, true) ? turn.reversi() : 0 : 0 ;
if (board.getMovablePoints(turn).size() == 0) {
if (board.getMovablePoints(turn.getReversi()).size() == 0) {
result.show();
result.text(L"result").text = Format(L"黒:",board.tileNum(Color::BLACK),L"\n白:",board.tileNum(Color::WHITE),L"\n", board.tileNum(Color::BLACK) == board.tileNum(Color::WHITE) ? L"引き分け" : board.tileNum(Color::BLACK) > board.tileNum(Color::WHITE) ? L"黒の勝ち" : L"白の勝ち");
if (result.button(L"play").pushed) {
*this = Reversi();
}
if (result.button(L"exit").pushed) {
System::Exit();
}
}else{
pass.show();
if (pass.button(L"OK").pushed) {
turn.reversi();
pass.hide();
}
}
}
}
}
};
}
void Main() {
rev::Reversi game;
game.main();
}