diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt
index e54ed6d0..3a30c07c 100644
--- a/.github/actions/spelling/expect.txt
+++ b/.github/actions/spelling/expect.txt
@@ -128,7 +128,9 @@ github
GLIBCXX
GNUC
google
+googletest
graphicsconst
+gtest
GRAPHICSVIEW
GWLP
halfmove
diff --git a/.vscode/settings.json b/.vscode/settings.json
index c8a9bddc..6691202e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -35,6 +35,8 @@
"fsanitize",
"gamewindow",
"gitee",
+ "googletest",
+ "gtest",
"GWLP",
"hhmmss",
"HMONITOR",
diff --git a/tests/gtest/gtest.vcxproj b/tests/gtest/gtest.vcxproj
index 33cd201d..6f219eb2 100644
--- a/tests/gtest/gtest.vcxproj
+++ b/tests/gtest/gtest.vcxproj
@@ -64,7 +64,6 @@
-
@@ -83,13 +82,8 @@
-
-
- Create
- Create
- Create
- Create
-
+
+
diff --git a/tests/gtest/gtest.vcxproj.filters b/tests/gtest/gtest.vcxproj.filters
index bb946921..2d8ae823 100644
--- a/tests/gtest/gtest.vcxproj.filters
+++ b/tests/gtest/gtest.vcxproj.filters
@@ -1,8 +1,7 @@
-
-
+
src
@@ -51,9 +50,9 @@
src
+
-
src
@@ -126,4 +125,7 @@
{a39da258-14bd-471b-a1bc-d434396da5ad}
+
+
+
\ No newline at end of file
diff --git a/tests/gtest/pch.cpp b/tests/gtest/pch.cpp
deleted file mode 100644
index 250fb277..00000000
--- a/tests/gtest/pch.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-//
-// pch.cpp
-//
-
-#include "pch.h"
diff --git a/tests/gtest/pch.h b/tests/gtest/pch.h
deleted file mode 100644
index 0572a70b..00000000
--- a/tests/gtest/pch.h
+++ /dev/null
@@ -1,7 +0,0 @@
-//
-// pch.h
-//
-
-#pragma once
-
-#include "gtest/gtest.h"
diff --git a/tests/gtest/stack_test.cpp b/tests/gtest/stack_test.cpp
new file mode 100644
index 00000000..53131880
--- /dev/null
+++ b/tests/gtest/stack_test.cpp
@@ -0,0 +1,105 @@
+// This file is part of Sanmill.
+// Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file)
+//
+// Sanmill 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 3 of the License, or
+// (at your option) any later version.
+//
+// Sanmill 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 this program. If not, see .
+
+#include "gtest/gtest.h"
+
+#include "stack.h"
+using namespace Sanmill;
+
+namespace {
+
+TEST(stackPushTest, stackTest)
+{
+ Stack stack;
+
+ EXPECT_TRUE(stack.empty());
+
+ stack.push(0);
+ EXPECT_EQ(stack.size(), 1);
+ EXPECT_EQ(stack[0], 0);
+ EXPECT_EQ(stack.top()[0], 0);
+ EXPECT_EQ(stack.begin()[0], 0);
+ EXPECT_EQ(stack.end()[-1], 0);
+ EXPECT_FALSE(stack.empty());
+
+ stack.push_back(1);
+ EXPECT_EQ(stack.size(), 2);
+ EXPECT_EQ(stack.length(), sizeof(int) * 2);
+ EXPECT_EQ(stack[1], 1);
+ EXPECT_EQ(stack.top()[0], 1);
+ EXPECT_EQ(stack.begin()[0], 0);
+ EXPECT_EQ(stack.end()[-1], 1);
+ EXPECT_FALSE(stack.empty());
+
+ stack.pop();
+ EXPECT_EQ(stack.size(), 1);
+ EXPECT_EQ(stack[1], 1);
+ EXPECT_EQ(stack.top()[0], 0);
+ EXPECT_EQ(stack.begin()[0], 0);
+ EXPECT_EQ(stack.end()[-1], 0);
+ EXPECT_FALSE(stack.empty());
+
+ stack.pop();
+ EXPECT_EQ(stack.size(), 0);
+ EXPECT_TRUE(stack.empty());
+
+ stack.push_back(0);
+ stack.push_back(1);
+ stack.push_back(2);
+ stack.push_back(3);
+ stack.push_back(4);
+ EXPECT_EQ(stack.size(), 5);
+ stack.erase(2);
+ EXPECT_EQ(stack.size(), 4);
+ EXPECT_EQ(stack[0], 0);
+ EXPECT_EQ(stack[1], 1);
+ EXPECT_EQ(stack[2], 3);
+ EXPECT_EQ(stack[3], 4);
+ stack.erase(0);
+ EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack[0], 1);
+ EXPECT_EQ(stack[1], 3);
+ EXPECT_EQ(stack[2], 4);
+ stack.erase(2);
+ EXPECT_EQ(stack.size(), 2);
+ EXPECT_EQ(stack[0], 1);
+ EXPECT_EQ(stack[1], 3);
+ stack.erase(0);
+ stack.erase(0);
+
+ //stack.erase(0);
+ // EXPECT_EQ(stack.size(), -1); // TODO(calcitem)
+
+ stack.push_back(0);
+ stack.push_back(1);
+ stack.push_back(2);
+ stack.push_back(3);
+ stack.push_back(4);
+ EXPECT_EQ(stack.size(), 5);
+ stack.clear();
+ EXPECT_EQ(stack.size(), 0);
+
+ stack.push_back(0);
+ stack.push_back(1);
+ Stack& stackRef = stack;
+ EXPECT_EQ(stack.size(), 2);
+
+ // TODO(calcitem)
+ //Stack anotherStack = stack;
+ //EXPECT_EQ(stack == anotherStack, true);
+}
+
+} // namespace
diff --git a/tests/gtest/test.cpp b/tests/gtest/test.cpp
deleted file mode 100644
index b5dae8d5..00000000
--- a/tests/gtest/test.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "pch.h"
-
-TEST(TestCaseName, TestName)
-{
- EXPECT_EQ(1, 1);
- EXPECT_TRUE(true);
-}
diff --git a/tests/gtest/types_test.cpp b/tests/gtest/types_test.cpp
new file mode 100644
index 00000000..538ab3e9
--- /dev/null
+++ b/tests/gtest/types_test.cpp
@@ -0,0 +1,189 @@
+// This file is part of Sanmill.
+// Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file)
+//
+// Sanmill 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 3 of the License, or
+// (at your option) any later version.
+//
+// Sanmill 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 this program. If not, see .
+
+#include "gtest/gtest.h"
+
+#include "types.h"
+
+namespace {
+
+TEST(TypesTest, toggleColor)
+{
+ EXPECT_EQ(~WHITE, BLACK);
+ EXPECT_EQ(~BLACK, WHITE);
+}
+
+TEST(TypesTest, makeSquare)
+{
+ EXPECT_EQ(make_square(FILE_A, RANK_1), SQ_8);
+ EXPECT_EQ(make_square(FILE_A, RANK_2), SQ_9);
+ EXPECT_EQ(make_square(FILE_A, RANK_3), SQ_10);
+ EXPECT_EQ(make_square(FILE_A, RANK_4), SQ_11);
+ EXPECT_EQ(make_square(FILE_A, RANK_5), SQ_12);
+ EXPECT_EQ(make_square(FILE_A, RANK_6), SQ_13);
+ EXPECT_EQ(make_square(FILE_A, RANK_7), SQ_14);
+ EXPECT_EQ(make_square(FILE_A, RANK_8), SQ_15);
+
+ EXPECT_EQ(make_square(FILE_B, RANK_1), SQ_16);
+ EXPECT_EQ(make_square(FILE_B, RANK_2), SQ_17);
+ EXPECT_EQ(make_square(FILE_B, RANK_3), SQ_18);
+ EXPECT_EQ(make_square(FILE_B, RANK_4), SQ_19);
+ EXPECT_EQ(make_square(FILE_B, RANK_5), SQ_20);
+ EXPECT_EQ(make_square(FILE_B, RANK_6), SQ_21);
+ EXPECT_EQ(make_square(FILE_B, RANK_7), SQ_22);
+ EXPECT_EQ(make_square(FILE_B, RANK_8), SQ_23);
+
+ EXPECT_EQ(make_square(FILE_C, RANK_1), SQ_24);
+ EXPECT_EQ(make_square(FILE_C, RANK_2), SQ_25);
+ EXPECT_EQ(make_square(FILE_C, RANK_3), SQ_26);
+ EXPECT_EQ(make_square(FILE_C, RANK_4), SQ_27);
+ EXPECT_EQ(make_square(FILE_C, RANK_5), SQ_28);
+ EXPECT_EQ(make_square(FILE_C, RANK_6), SQ_29);
+ EXPECT_EQ(make_square(FILE_C, RANK_7), SQ_30);
+ EXPECT_EQ(make_square(FILE_C, RANK_8), SQ_31);
+}
+
+TEST(TypesTest, makePiece)
+{
+ EXPECT_EQ(make_piece(WHITE), W_STONE);
+ EXPECT_EQ(make_piece(BLACK), B_STONE);
+
+ EXPECT_EQ(make_piece(WHITE, WHITE_STONE), W_STONE);
+ EXPECT_EQ(make_piece(BLACK, WHITE_STONE), B_STONE);
+ EXPECT_EQ(make_piece(NOCOLOR, BAN), BAN_STONE);
+}
+
+TEST(TypesTest, colorOf)
+{
+ EXPECT_EQ(color_of(W_STONE), WHITE);
+ EXPECT_EQ(color_of(B_STONE), BLACK);
+}
+
+TEST(TypesTest, isOk)
+{
+ EXPECT_TRUE(is_ok(SQ_NONE));
+ EXPECT_FALSE(is_ok(SQ_7));
+ EXPECT_TRUE(is_ok(SQ_8));
+ EXPECT_TRUE(is_ok(SQ_16));
+ EXPECT_TRUE(is_ok(SQ_24));
+ EXPECT_TRUE(is_ok(SQ_31));
+ EXPECT_FALSE(is_ok(SQ_32));
+ EXPECT_FALSE(is_ok(SQ_33));
+ EXPECT_FALSE(is_ok(SQ_39));
+
+ EXPECT_FALSE(is_ok(make_move(SQ_8, SQ_8)));
+}
+
+TEST(TypesTest, fileOf)
+{
+ EXPECT_EQ(file_of(SQ_8), FILE_A);
+ EXPECT_EQ(file_of(SQ_9), FILE_A);
+ EXPECT_EQ(file_of(SQ_10), FILE_A);
+ EXPECT_EQ(file_of(SQ_11), FILE_A);
+ EXPECT_EQ(file_of(SQ_12), FILE_A);
+ EXPECT_EQ(file_of(SQ_13), FILE_A);
+ EXPECT_EQ(file_of(SQ_14), FILE_A);
+ EXPECT_EQ(file_of(SQ_15), FILE_A);
+
+ EXPECT_EQ(file_of(SQ_16), FILE_B);
+ EXPECT_EQ(file_of(SQ_17), FILE_B);
+ EXPECT_EQ(file_of(SQ_18), FILE_B);
+ EXPECT_EQ(file_of(SQ_19), FILE_B);
+ EXPECT_EQ(file_of(SQ_20), FILE_B);
+ EXPECT_EQ(file_of(SQ_21), FILE_B);
+ EXPECT_EQ(file_of(SQ_22), FILE_B);
+ EXPECT_EQ(file_of(SQ_23), FILE_B);
+
+ EXPECT_EQ(file_of(SQ_24), FILE_C);
+ EXPECT_EQ(file_of(SQ_25), FILE_C);
+ EXPECT_EQ(file_of(SQ_26), FILE_C);
+ EXPECT_EQ(file_of(SQ_27), FILE_C);
+ EXPECT_EQ(file_of(SQ_28), FILE_C);
+ EXPECT_EQ(file_of(SQ_29), FILE_C);
+ EXPECT_EQ(file_of(SQ_30), FILE_C);
+ EXPECT_EQ(file_of(SQ_31), FILE_C);
+}
+
+TEST(TypesTest, rankOf)
+{
+ EXPECT_EQ(rank_of(SQ_8), RANK_1);
+ EXPECT_EQ(rank_of(SQ_9), RANK_2);
+ EXPECT_EQ(rank_of(SQ_10), RANK_3);
+ EXPECT_EQ(rank_of(SQ_11), RANK_4);
+ EXPECT_EQ(rank_of(SQ_12), RANK_5);
+ EXPECT_EQ(rank_of(SQ_13), RANK_6);
+ EXPECT_EQ(rank_of(SQ_14), RANK_7);
+ EXPECT_EQ(rank_of(SQ_15), RANK_8);
+
+ EXPECT_EQ(rank_of(SQ_16), RANK_1);
+ EXPECT_EQ(rank_of(SQ_17), RANK_2);
+ EXPECT_EQ(rank_of(SQ_18), RANK_3);
+ EXPECT_EQ(rank_of(SQ_19), RANK_4);
+ EXPECT_EQ(rank_of(SQ_20), RANK_5);
+ EXPECT_EQ(rank_of(SQ_21), RANK_6);
+ EXPECT_EQ(rank_of(SQ_22), RANK_7);
+ EXPECT_EQ(rank_of(SQ_23), RANK_8);
+
+ EXPECT_EQ(rank_of(SQ_24), RANK_1);
+ EXPECT_EQ(rank_of(SQ_25), RANK_2);
+ EXPECT_EQ(rank_of(SQ_26), RANK_3);
+ EXPECT_EQ(rank_of(SQ_27), RANK_4);
+ EXPECT_EQ(rank_of(SQ_28), RANK_5);
+ EXPECT_EQ(rank_of(SQ_29), RANK_6);
+ EXPECT_EQ(rank_of(SQ_30), RANK_7);
+ EXPECT_EQ(rank_of(SQ_31), RANK_8);
+}
+
+TEST(TypesTest, makeMove)
+{
+ Move m = MOVE_NONE;
+ Square originFrom = SQ_NONE;
+ Square originTo = SQ_NONE;
+ Square from = SQ_NONE;
+ Square to = SQ_NONE;
+
+ originFrom = SQ_8;
+ originTo = SQ_9;
+ m = make_move(originFrom, originTo);
+ from = from_sq(m);
+ to = to_sq(m);
+ EXPECT_EQ(from, originFrom);
+ EXPECT_EQ(to, originTo);
+
+ originFrom = SQ_23;
+ originTo = SQ_31;
+ m = make_move(originFrom, originTo);
+ from = from_sq(m);
+ to = to_sq(m);
+ EXPECT_EQ(from, originFrom);
+ EXPECT_EQ(to, originTo);
+
+ originFrom = SQ_20;
+ originTo = SQ_28;
+ m = make_move(originFrom, originTo);
+ from = from_sq(m);
+ to = to_sq(m);
+ EXPECT_EQ(from, originFrom);
+ EXPECT_EQ(to, originTo);
+}
+
+TEST(TypesTest, reverseMove)
+{
+ EXPECT_EQ(reverse_move(make_move(SQ_8, SQ_9)), make_move(SQ_9, SQ_8));
+ EXPECT_EQ(reverse_move(make_move(SQ_30, SQ_31)), make_move(SQ_31, SQ_30));
+}
+
+} // namespace