diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..1a7a787 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +# Use C++ build environment. +language: cpp + +before_install: + - sudo apt-get install cmake + +# Run the build script. +script: + - mkdir build + - cd build + - cmake .. + - make + - ./ompeval diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b201890 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.0) +project(OMPEval) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") +set(SOURCE_FILES ompeval.cpp benchmark.cpp omp/CardRange.cpp omp/CardRange.h omp/CombinedRange.cpp omp/CombinedRange.h omp/Constants.h omp/EquityCalculator.cpp omp/EquityCalculator.h omp/Hand.h omp/HandEvaluator.cpp omp/HandEvaluator.h omp/Random.h omp/Util.h libdivide/libdivide.h) +add_executable (ompeval ${SOURCE_FILES}) \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index 647b286..0000000 --- a/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -CXXFLAGS += -O3 -std=c++11 -Wall -Wpedantic - -ifdef SYSTEMROOT - CXXFLAGS += -lpthread -else - CXXFLAGS += -pthread -endif - -ifeq ($(SSE4),1) - CXXFLAGS += -msse4.2 -endif - -SRCS := $(wildcard omp/*.cpp) -OBJS := ${SRCS:.cpp=.o} - -all: lib/ompeval.a test - -lib: - mkdir lib - -lib/ompeval.a: $(OBJS) | lib - ar rcs $@ $^ - -test: test.cpp benchmark.cpp lib/ompeval.a - $(CXX) $(CXXFLAGS) -o $@ $^ - -clean: - $(RM) test test.exe lib/ompeval.a $(OBJS) diff --git a/README.md b/README.md index fdb8ce0..5a52000 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Rand2: 520 87 466 62 529 72 ``` ###Usage ```c++ -#include +#include "omp/HandEvaluator.h" #include using namespace omp; int main() @@ -42,9 +42,9 @@ int main() In x64 mode both Monte carlo and enumeration are roughly 2-10x faster (per thread) than the free version of Equilab (except headsup enumeration where EquiLab uses precalculated results). -###Basic usage +### Basic usage ```c++ -#include +#include "omp/EquityCalculator.h" #include int main() { @@ -55,9 +55,9 @@ int main() std::cout << r.equity[0] << " " << r.equity[1] << std::endl; } ``` -###Advanced usage +### Advanced usage ```c++ -#include +#include "omp/EquityCalculator.h" #include using namespace omp; using namespace std; @@ -86,7 +86,13 @@ int main() ``` ## Building -To build a static library (./lib/ompeval.a) on Unix systems, use `make`. To enable -msse4.1 switch, use `make SSE4=1`. Run tests with `./test`. For Windows there's currently no build files, so you will have to compile everything manually. The code has been tested with MSVC2013, TDM-GCC 5.1.0 and MinGW64 6.1, Clang 3.8.1 on Cygwin, and g++ 4.8 on Debian. +To build a static library (`./build/ompeval`) on Unix systems, use `cmake`. To enable -msse4.1 switch, use `make SSE4=1`. For Windows there's currently no build files, so you will have to compile everything manually. The code has been tested with MSVC2013, TDM-GCC 5.1.0 and MinGW64 6.1, Clang 3.8.1 on Cygwin, and g++ 7.4.0 on Debian. See build commands below: +```bash +mkdir build +cd build +cmake .. +make +``` ## About the algorithms used diff --git a/omp/EquityCalculator.h b/omp/EquityCalculator.h index 934787b..b7e6c57 100644 --- a/omp/EquityCalculator.h +++ b/omp/EquityCalculator.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace omp { diff --git a/test.cpp b/ompeval.cpp similarity index 90% rename from test.cpp rename to ompeval.cpp index f0437c9..9276c77 100644 --- a/test.cpp +++ b/ompeval.cpp @@ -415,4 +415,34 @@ int main() void benchmark(); benchmark(); cout << endl << "Done." << endl; + + HandEvaluator eval; + Hand h = Hand::empty(); // Final hand must include empty() exactly once! + h += Hand(51) + Hand(48) + Hand(0) + Hand(1) + Hand(2); // AdAs2s2h2c + std::cout << eval.evaluate(h) << std::endl; // 28684 = 7 * 4096 + 12 + + EquityCalculator eq; + eq.start({"AK", "QQ"}); + eq.wait(); + auto r1 = eq.getResults(); + std::cout << r1.equity[0] << " " << r1.equity[1] << std::endl; + + vector ranges{"QQ+,AKs,AcQc", "A2s+", "random"}; + uint64_t board = CardRange::getCardMask("2c4c5h"); + uint64_t dead = CardRange::getCardMask("Jc"); + double stdErrMargin = 2e-5; // stop when standard error below 0.002% + auto callback = [&eq](const EquityCalculator::Results& results) { + cout << results.equity[0] << " " << 100 * results.progress + << " " << 1e-6 * results.intervalSpeed << endl; + if (results.time > 5) // Stop after 5s + eq.stop(); + }; + double updateInterval = 0.25; // Callback called every 0.25s. + unsigned threads = 0; // max hardware parallelism (default) + eq.start(ranges, board, dead, false, stdErrMargin, callback, updateInterval, threads); + eq.wait(); + auto r2 = eq.getResults(); + cout << endl << r2.equity[0] << " " << r2.equity[1] << " " << r2.equity[2] << endl; + cout << r2.wins[0] << " " << r2.wins[1] << " " << r2.wins[2] << endl; + cout << r2.hands << " " << r2.time << " " << 1e-6 * r2.speed << " " << r2.stdev << endl; }