Commit e4385b59 authored by mercury233's avatar mercury233

Merge branch 'master' into patch-sum-param

parents 076284d3 8e539a65
name: Automated Test Build
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build-windows:
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download lua
id: lua
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://www.lua.org/ftp/lua-5.4.8.tar.gz
- name: Lua
run: |
tar -xzf ${{ steps.lua.outputs.filepath }}
move lua-5.4.8 lua
- name: Download premake
id: premake
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/premake/premake-core/releases/download/v5.0.0-beta7/premake-5.0.0-beta7-windows.zip
- name: Premake
run: |
mkdir premake-5
tar -C premake-5 -xzf ${{ steps.premake.outputs.filepath }}
copy premake\lua.lua lua\premake5.lua
copy premake\dll.lua dll.lua
.\premake-5\premake5.exe vs2022 --file=dll.lua
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Build x32
run: |
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=Win32"
- name: Build x64
run: |
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=x64"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: ocgcore-windows
path: |
build\bin\x32\Release\ocgcore.dll
build\bin\x64\Release\ocgcore.dll
- name: GitHub Release
if: github.event_name == 'push'
uses: salix5/action-automatic-releases@node20
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: true
title: "Development Build"
files: |
build/bin/x64/Release/ocgcore.dll
build-linux:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib
- name: Download lua
id: lua
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://www.lua.org/ftp/lua-5.4.8.tar.gz
- name: Lua
run: |
tar -xzf ${{ steps.lua.outputs.filepath }}
mv lua-5.4.8 lua
- name: Download premake
id: premake
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/premake/premake-core/releases/download/v5.0.0-beta7/premake-5.0.0-beta7-linux.tar.gz
- name: Premake
run: |
mkdir premake-5
tar -C premake-5 -xzf ${{ steps.premake.outputs.filepath }}
cp premake/lua.lua lua/premake5.lua
cp premake/dll.lua dll.lua
chmod +x premake-5/premake5
./premake-5/premake5 gmake --file=dll.lua
- name: Build x32
run: |
cd build
make -j 4 config=release_x32
cd ..
- name: Build x64
run: |
cd build
make -j 4 config=release_x64
cd ..
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: ocgcore-linux
path: |
build/bin/x32/Release/libocgcore.so
build/bin/x64/Release/libocgcore.so
/.vscode/
/build/
/lua/
/temp/
/premake-5/
/premake5.exe
...@@ -4,64 +4,71 @@ ...@@ -4,64 +4,71 @@
The core logic and lua script processor of YGOPro. This library can be made external of the project and used to power server technologies. It maintains a state engine that is manipulated by Lua scripts using manipulation functions it exposes. The core logic and lua script processor of YGOPro. This library can be made external of the project and used to power server technologies. It maintains a state engine that is manipulated by Lua scripts using manipulation functions it exposes.
## Compiling ## Compiling
### 1.) Download Fluorohydride/ygopro In most cases, what you want to compile is the main program of YGOPro. You should refer to the main YGOPro project's [wiki](https://github.com/Fluorohydride/ygopro/wiki).
Start by downloading the most parent of the source code. The team developing this project are the defacto edge and experts in our community. The most upto date `ocgcore` is a compiled dll version of the `Fluorohydride/ygopro/ocgcore` folders project. If you want to compile the dynamic link library of this repository (ocgcore.dll), you can refer to [this script](https://github.com/Fluorohydride/ygopro-core/blob/master/.github/workflows/build.yml).
### 2.) Install Premake4 and Visual Studio 2010 (or later). ## Exposed Functions
Download premake4.exe, put it in `c:\windows` or a similar folder that is globally accessible via `cmd` or PowerShell. Install Visual Studio 2010, it is the system used for the guide because other parts of the project use C# and most the development team are Windows users.
### 3.) Download dependencies The 3 functions need to be provided to the core so it can get card and database information.
Dependencies are absent from the main project. There is information on how to build them but the easiest thing to do is to download the following folders from a [soarqin/ygopro](https://github.com/soarqin/ygopro) fork and simply copy them into the `Fluorohydride/ygopro` folder. - `void set_script_reader(script_reader f);`
Interface provided returns scripts based on number that corresponds to a lua file, send in a string.
* event - `void set_card_reader(card_reader f);`
* freetype Interface provided function that provides database information from the `data` table of `cards.cdb`.
* irrlicht
* lua
* sqlite3
### 4.) Create the project files - `void set_message_handler(message_handler f);`
Run the following commands from the command line in the `Fluorohydride/ygopro` folder. Interface provided function that handles error messages.
` premake4 /help ` These functions create the game itself and then manipulate it.
` premake4 vs2010 ` - `intptr_t create_duel(uint_fast32_t seed);`
Create a the instance of the duel with a PRNG seed.
If you are not using Visual Studio 2010 or higher, make the needed adjustments. In the file system open `Fluorohydride/ygopro/build` folder open the `ygo` project. - `void start_duel(intptr_t pduel, uint32_t options);`
Start the duel.
### 5.) Build the system - `void end_duel(intptr_t pduel);`
Make sure the code actually compiles. Compile them in the following order one by one: End the duel.
* lua - `void set_player_info(intptr_t pduel, int32_t playerid, int32_t lp, int32_t startcount, int32_t drawcount);`
* sqlite3 Set up the duel information.
* ocgcore
This should provide you with `ocgcore.lib` in the build output folder. `YGOCore` requires a `*.dll`; in `ocgcore` project properties change it to a dynamically linked library. Recompile, it should fail with an error indicating missing dependencies. Right click the project, add an existing file. Add `lua.lib` from the build folder to the project. It should now compile. - `void get_log_message(intptr_t pduel, char* buf);`
## Exposed Functions - `int32_t get_message(intptr_t pduel, byte* buf);`
These three function need to be provided to the core so it can get card and database information. - `int32_t process(intptr_t pduel);`
- `void set_script_reader(script_reader f);` : Interface provided returns scripts based on number that corresponds to a lua file, send in a string. Do a game tick.
- `void set_card_reader(card_reader f);` : Interface provided function that provides database information from the `data` table of `cards.cdb`. - `void new_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t playerid, uint8_t location, uint8_t sequence, uint8_t position);`
Add a card to the duel state.
- `void set_message_handler(message_handler f);` : Interface provided function that handles errors - `void new_tag_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t location);`
Add a new card to the tag pool.
These functions create the game itself and then manipulate it. - `int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);`
- `ptr create_duel(uint32 seed);` : Create a the instance of the duel using a random number. Get a card in a specific location.
- `void start_duel(ptr pduel, int32 options);` : Starts the duel
- `void end_duel(ptr pduel);` : ends the duel - `int32_t query_field_count(intptr_t pduel, uint8_t playerid, uint8_t location);`
- `void set_player_info(ptr pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount);` sets the duel up Get the number of cards in a specific location.
- `void get_log_message(ptr pduel, byte* buf);`
- `int32 get_message(ptr pduel, byte* buf);` - `int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);`
- `int32 process(ptr pduel);` : do a game tick Get all cards in some location.
- `void new_card(ptr pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 position);` : add a card to the duel state.
- `void new_tag_card(ptr pduel, uint32 code, uint8 owner, uint8 location);` : add a new card to the tag pool. - `int32_t query_field_info(intptr_t pduel, byte* buf);`
- `int32 query_card(ptr pduel, uint8 playerid, uint8 location, uint8 sequence, int32 query_flag, byte* buf, int32 use_cache);` : find out about a card in a specific spot.
- `int32 query_field_count(ptr pduel, uint8 playerid, uint8 location);` : Get the number of cards in a specific field/zone. - `void set_responsei(intptr_t pduel, int32_t value);`
- `int32 query_field_card(ptr pduel, uint8 playerid, uint8 location, int32 query_flag, byte* buf, int32 use_cache);`
- `int32 query_field_info(ptr pduel, byte* buf);` - `void set_responseb(intptr_t pduel, byte* buf);`
- `void set_responsei(ptr pduel, int32 value);`
- `void set_responseb(ptr pduel, byte* buf);` - `int32_t preload_script(intptr_t pduel, const char* script_name);`
- `int32 preload_script(ptr pduel, char* script, int32 len);`
- `byte* default_script_reader(const char* script_name, int* len);`
The default script reader using `fread`.
# Lua functions # Lua functions
`interpreter.cpp` - `libcard.cpp`
- `libdebug.cpp`
- `libduel.cpp`
- `libeffect.cpp`
- `libgroup.cpp`
#ifndef CORE_BUFFER_H
#define CORE_BUFFER_H
#include <cstdio>
#include <cstring>
#include <vector>
inline void buffer_read_block(unsigned char*& p, void* dest, size_t size) {
std::memcpy(dest, p, size);
p += size;
}
template<typename T>
inline T buffer_read(unsigned char*& p) {
T ret{};
std::memcpy(&ret, p, sizeof(T));
p += sizeof(T);
return ret;
}
inline void buffer_write_block(unsigned char*& p, const void* src, size_t size) {
std::memcpy(p, src, size);
p += size;
}
template<typename T>
inline void buffer_write(unsigned char*& p, T value) {
std::memcpy(p, &value, sizeof(T));
p += sizeof(T);
}
inline void vector_write_block(std::vector<unsigned char>& buffer, const void* src, size_t size) {
const auto len = buffer.size();
buffer.resize(len + size);
std::memcpy(&buffer[len], src, size);
}
template<typename T>
inline void vector_write(std::vector<unsigned char>& buffer, T value) {
vector_write_block(buffer, &value, sizeof(T));
}
inline void vector_fread(std::vector<unsigned char>& buffer, FILE* fp) {
unsigned char temp[4096]{};
while (size_t len = std::fread(temp, 1, sizeof temp, fp))
vector_write_block(buffer, temp, len);
std::fclose(fp);
}
#endif // !CORE_BUFFER_H
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
#ifndef CARD_DATA_H_
#define CARD_DATA_H_
#include <cstring>
#include <unordered_map>
#include "common.h"
constexpr int CARD_ARTWORK_VERSIONS_OFFSET = 20;
constexpr int SIZE_SETCODE = 16;
constexpr uint32_t CARD_BLACK_LUSTER_SOLDIER2 = 5405695;
//double name
constexpr uint32_t CARD_MARINE_DOLPHIN = 78734254;
constexpr uint32_t CARD_TWINKLE_MOSS = 13857930;
constexpr uint32_t CARD_TIMAEUS = 1784686;
constexpr uint32_t CARD_CRITIAS = 11082056;
constexpr uint32_t CARD_HERMOS = 46232525;
const std::unordered_map<uint32_t, uint32_t> second_code = {
{CARD_MARINE_DOLPHIN, 17955766u},
{CARD_TWINKLE_MOSS, 17732278u},
{CARD_TIMAEUS, 10000050u},
{CARD_CRITIAS, 10000060u},
{CARD_HERMOS, 10000070u},
};
struct card_data {
uint32_t code{};
uint32_t alias{};
uint16_t setcode[SIZE_SETCODE]{};
uint32_t type{};
uint32_t level{};
uint32_t attribute{};
uint32_t race{};
int32_t attack{};
int32_t defense{};
uint32_t lscale{};
uint32_t rscale{};
uint32_t link_marker{};
void clear() {
std::memset(this, 0, sizeof(card_data));
}
bool is_setcode(uint32_t value) const {
const uint16_t settype = value & 0x0fff;
const uint16_t setsubtype = value & 0xf000;
for (auto& x : setcode) {
if ((x & 0x0fff) == settype && (x & setsubtype) == setsubtype)
return true;
if (!x)
return false;
}
return false;
}
bool is_alternative() const {
if (code == CARD_BLACK_LUSTER_SOLDIER2)
return false;
return alias && (alias < code + CARD_ARTWORK_VERSIONS_OFFSET) && (code < alias + CARD_ARTWORK_VERSIONS_OFFSET);
}
void set_setcode(uint64_t value) {
int ctr = 0;
while (value) {
if (value & 0xffff) {
setcode[ctr] = value & 0xffff;
++ctr;
}
value >>= 16;
}
if (ctr < SIZE_SETCODE)
std::memset(setcode + ctr, 0, (SIZE_SETCODE - ctr) * sizeof(uint16_t));
}
uint32_t get_original_code() const {
return is_alternative() ? alias : code;
}
};
#endif /* CARD_DATA_H_ */
...@@ -9,16 +9,12 @@ ...@@ -9,16 +9,12 @@
#define COMMON_H_ #define COMMON_H_
#include <stdint.h> #include <stdint.h>
typedef unsigned long long uint64; #include <assert.h>
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef unsigned char byte; typedef unsigned char byte;
typedef long long int64;
typedef int int32; inline bool check_playerid(int32_t playerid) {
typedef short int16; return playerid >= 0 && playerid <= 1;
typedef signed char int8; }
typedef int BOOL;
#define MATCH_ALL(x,y) (((x)&(y))==(y)) #define MATCH_ALL(x,y) (((x)&(y))==(y))
#define MATCH_ANY(x,y) ((x)&(y)) #define MATCH_ANY(x,y) ((x)&(y))
...@@ -30,25 +26,35 @@ typedef int BOOL; ...@@ -30,25 +26,35 @@ typedef int BOOL;
#define OPERATION_CANCELED -1 #define OPERATION_CANCELED -1
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
#ifndef NULL
#define NULL 0 #define SIZE_MESSAGE_BUFFER 0x2000
#endif #define SIZE_RETURN_VALUE 512
struct card_sort { #define SIZE_AI_NAME 128
bool operator()(void* const & c1, void* const & c2) const; #define SIZE_HINT_MSG 1024
};
#define PROCESSOR_BUFFER_LEN 0x0fffffff
#define PROCESSOR_FLAG 0xf0000000
#define PROCESSOR_NONE 0
#define PROCESSOR_WAITING 0x10000000
#define PROCESSOR_END 0x20000000
#define MASTER_RULE3 3 //Master Rule 3 (2014)
#define NEW_MASTER_RULE 4 //New Master Rule (2017)
#define MASTER_RULE_2020 5 //Master Rule 2020
#define CURRENT_RULE 5
//Locations //Locations
#define LOCATION_DECK 0x01 // #define LOCATION_DECK 0x01U
#define LOCATION_HAND 0x02 // #define LOCATION_HAND 0x02U
#define LOCATION_MZONE 0x04 // #define LOCATION_MZONE 0x04U
#define LOCATION_SZONE 0x08 // #define LOCATION_SZONE 0x08U
#define LOCATION_GRAVE 0x10 // #define LOCATION_GRAVE 0x10U
#define LOCATION_REMOVED 0x20 // #define LOCATION_REMOVED 0x20U
#define LOCATION_EXTRA 0x40 // #define LOCATION_EXTRA 0x40U
#define LOCATION_OVERLAY 0x80 // #define LOCATION_OVERLAY 0x80U
#define LOCATION_ONFIELD 0x0c // #define LOCATION_ONFIELD (LOCATION_MZONE | LOCATION_SZONE)
#define LOCATION_FZONE 0x100 // #define LOCATION_FZONE 0x100U
#define LOCATION_PZONE 0x200 // #define LOCATION_PZONE 0x200U
//For redirect //For redirect
#define LOCATION_DECKBOT 0x10001 //Return to deck bottom #define LOCATION_DECKBOT 0x10001 //Return to deck bottom
#define LOCATION_DECKSHF 0x20001 //Return to deck and shuffle #define LOCATION_DECKSHF 0x20001 //Return to deck and shuffle
...@@ -69,6 +75,10 @@ struct card_sort { ...@@ -69,6 +75,10 @@ struct card_sort {
//Flip effect flags //Flip effect flags
#define NO_FLIP_EFFECT 0x10000 #define NO_FLIP_EFFECT 0x10000
//Move to field flags
#define RETURN_TEMP_REMOVE_TO_FIELD 1
#define RETURN_TRAP_MONSTER_TO_SZONE 2
//Types //Types
#define TYPE_MONSTER 0x1 // #define TYPE_MONSTER 0x1 //
#define TYPE_SPELL 0x2 // #define TYPE_SPELL 0x2 //
...@@ -96,7 +106,10 @@ struct card_sort { ...@@ -96,7 +106,10 @@ struct card_sort {
#define TYPE_SPSUMMON 0x2000000 // #define TYPE_SPSUMMON 0x2000000 //
#define TYPE_LINK 0x4000000 // #define TYPE_LINK 0x4000000 //
#define TYPES_EXTRA_DECK (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)
//Attributes //Attributes
#define ATTRIBUTES_COUNT 7
#define ATTRIBUTE_ALL 0x7f // #define ATTRIBUTE_ALL 0x7f //
#define ATTRIBUTE_EARTH 0x01 // #define ATTRIBUTE_EARTH 0x01 //
#define ATTRIBUTE_WATER 0x02 // #define ATTRIBUTE_WATER 0x02 //
...@@ -107,6 +120,8 @@ struct card_sort { ...@@ -107,6 +120,8 @@ struct card_sort {
#define ATTRIBUTE_DEVINE 0x40 // #define ATTRIBUTE_DEVINE 0x40 //
//Races //Races
#define RACES_COUNT 26
#define RACE_ALL 0x3ffffff
#define RACE_WARRIOR 0x1 // #define RACE_WARRIOR 0x1 //
#define RACE_SPELLCASTER 0x2 // #define RACE_SPELLCASTER 0x2 //
#define RACE_FAIRY 0x4 // #define RACE_FAIRY 0x4 //
...@@ -132,6 +147,7 @@ struct card_sort { ...@@ -132,6 +147,7 @@ struct card_sort {
#define RACE_CREATORGOD 0x400000 // #define RACE_CREATORGOD 0x400000 //
#define RACE_WYRM 0x800000 // #define RACE_WYRM 0x800000 //
#define RACE_CYBERSE 0x1000000 // #define RACE_CYBERSE 0x1000000 //
#define RACE_ILLUSION 0x2000000 //
//Reason //Reason
#define REASON_DESTROY 0x1 // #define REASON_DESTROY 0x1 //
...@@ -162,29 +178,33 @@ struct card_sort { ...@@ -162,29 +178,33 @@ struct card_sort {
#define REASON_REVEAL 0x8000000 // #define REASON_REVEAL 0x8000000 //
#define REASON_LINK 0x10000000 // #define REASON_LINK 0x10000000 //
#define REASON_LOST_OVERLAY 0x20000000 // #define REASON_LOST_OVERLAY 0x20000000 //
#define REASON_MAINTENANCE 0x40000000 //
#define REASON_ACTION 0x80000000 //
#define REASONS_PROCEDURE (REASON_SYNCHRO | REASON_XYZ | REASON_LINK)
//Status //Status
#define STATUS_DISABLED 0x0001 // #define STATUS_DISABLED 0x0001
#define STATUS_TO_ENABLE 0x0002 // #define STATUS_TO_ENABLE 0x0002
#define STATUS_TO_DISABLE 0x0004 // #define STATUS_TO_DISABLE 0x0004
#define STATUS_PROC_COMPLETE 0x0008 // #define STATUS_PROC_COMPLETE 0x0008
#define STATUS_SET_TURN 0x0010 // #define STATUS_SET_TURN 0x0010
#define STATUS_NO_LEVEL 0x0020 // #define STATUS_NO_LEVEL 0x0020
#define STATUS_BATTLE_RESULT 0x0040 // #define STATUS_BATTLE_RESULT 0x0040
#define STATUS_SPSUMMON_STEP 0x0080 // #define STATUS_SPSUMMON_STEP 0x0080
#define STATUS_FORM_CHANGED 0x0100 // #define STATUS_CANNOT_CHANGE_FORM 0x0100
#define STATUS_SUMMONING 0x0200 // #define STATUS_SUMMONING 0x0200
#define STATUS_EFFECT_ENABLED 0x0400 // #define STATUS_EFFECT_ENABLED 0x0400
#define STATUS_SUMMON_TURN 0x0800 // #define STATUS_SUMMON_TURN 0x0800
#define STATUS_DESTROY_CONFIRMED 0x1000 // #define STATUS_DESTROY_CONFIRMED 0x1000
#define STATUS_LEAVE_CONFIRMED 0x2000 // #define STATUS_LEAVE_CONFIRMED 0x2000
#define STATUS_BATTLE_DESTROYED 0x4000 // #define STATUS_BATTLE_DESTROYED 0x4000
#define STATUS_COPYING_EFFECT 0x8000 // #define STATUS_COPYING_EFFECT 0x8000
#define STATUS_CHAINING 0x10000 // #define STATUS_CHAINING 0x10000
#define STATUS_SUMMON_DISABLED 0x20000 // #define STATUS_SUMMON_DISABLED 0x20000
#define STATUS_ACTIVATE_DISABLED 0x40000 // #define STATUS_ACTIVATE_DISABLED 0x40000
#define STATUS_EFFECT_REPLACED 0x80000 #define STATUS_EFFECT_REPLACED 0x80000
#define STATUS_FUTURE_FUSION 0x100000 #define STATUS_FLIP_SUMMONING 0x100000
#define STATUS_ATTACK_CANCELED 0x200000 #define STATUS_ATTACK_CANCELED 0x200000
#define STATUS_INITIALIZING 0x400000 #define STATUS_INITIALIZING 0x400000
#define STATUS_TO_HAND_WITHOUT_CONFIRM 0x800000 #define STATUS_TO_HAND_WITHOUT_CONFIRM 0x800000
...@@ -195,6 +215,7 @@ struct card_sort { ...@@ -195,6 +215,7 @@ struct card_sort {
#define STATUS_OPPO_BATTLE 0x10000000 #define STATUS_OPPO_BATTLE 0x10000000
#define STATUS_FLIP_SUMMON_TURN 0x20000000 #define STATUS_FLIP_SUMMON_TURN 0x20000000
#define STATUS_SPSUMMON_TURN 0x40000000 #define STATUS_SPSUMMON_TURN 0x40000000
#define STATUS_FLIP_SUMMON_DISABLED 0x80000000
//Query list //Query list
#define QUERY_CODE 0x1 #define QUERY_CODE 0x1
...@@ -234,12 +255,12 @@ struct card_sort { ...@@ -234,12 +255,12 @@ struct card_sort {
//Messages //Messages
#define MSG_RETRY 1 #define MSG_RETRY 1
#define MSG_HINT 2 #define MSG_HINT 2
#define MSG_WAITING 3 //#define MSG_WAITING 3
#define MSG_START 4 //#define MSG_START 4
#define MSG_WIN 5 #define MSG_WIN 5
#define MSG_UPDATE_DATA 6 //#define MSG_UPDATE_DATA 6
#define MSG_UPDATE_CARD 7 //#define MSG_UPDATE_CARD 7
#define MSG_REQUEST_DECK 8 //#define MSG_REQUEST_DECK 8
#define MSG_SELECT_BATTLECMD 10 #define MSG_SELECT_BATTLECMD 10
#define MSG_SELECT_IDLECMD 11 #define MSG_SELECT_IDLECMD 11
#define MSG_SELECT_EFFECTYN 12 #define MSG_SELECT_EFFECTYN 12
...@@ -250,7 +271,6 @@ struct card_sort { ...@@ -250,7 +271,6 @@ struct card_sort {
#define MSG_SELECT_PLACE 18 #define MSG_SELECT_PLACE 18
#define MSG_SELECT_POSITION 19 #define MSG_SELECT_POSITION 19
#define MSG_SELECT_TRIBUTE 20 #define MSG_SELECT_TRIBUTE 20
//#define MSG_SORT_CHAIN 21
#define MSG_SELECT_COUNTER 22 #define MSG_SELECT_COUNTER 22
#define MSG_SELECT_SUM 23 #define MSG_SELECT_SUM 23
#define MSG_SELECT_DISFIELD 24 #define MSG_SELECT_DISFIELD 24
...@@ -260,7 +280,7 @@ struct card_sort { ...@@ -260,7 +280,7 @@ struct card_sort {
#define MSG_CONFIRM_CARDS 31 #define MSG_CONFIRM_CARDS 31
#define MSG_SHUFFLE_DECK 32 #define MSG_SHUFFLE_DECK 32
#define MSG_SHUFFLE_HAND 33 #define MSG_SHUFFLE_HAND 33
#define MSG_REFRESH_DECK 34 //#define MSG_REFRESH_DECK 34
#define MSG_SWAP_GRAVE_DECK 35 #define MSG_SWAP_GRAVE_DECK 35
#define MSG_SHUFFLE_SET_CARD 36 #define MSG_SHUFFLE_SET_CARD 36
#define MSG_REVERSE_DECK 37 #define MSG_REVERSE_DECK 37
...@@ -287,7 +307,7 @@ struct card_sort { ...@@ -287,7 +307,7 @@ struct card_sort {
#define MSG_CHAIN_END 74 #define MSG_CHAIN_END 74
#define MSG_CHAIN_NEGATED 75 #define MSG_CHAIN_NEGATED 75
#define MSG_CHAIN_DISABLED 76 #define MSG_CHAIN_DISABLED 76
#define MSG_CARD_SELECTED 80 //#define MSG_CARD_SELECTED 80
#define MSG_RANDOM_SELECTED 81 #define MSG_RANDOM_SELECTED 81
#define MSG_BECOME_TARGET 83 #define MSG_BECOME_TARGET 83
#define MSG_DRAW 90 #define MSG_DRAW 90
...@@ -295,7 +315,7 @@ struct card_sort { ...@@ -295,7 +315,7 @@ struct card_sort {
#define MSG_RECOVER 92 #define MSG_RECOVER 92
#define MSG_EQUIP 93 #define MSG_EQUIP 93
#define MSG_LPUPDATE 94 #define MSG_LPUPDATE 94
#define MSG_UNEQUIP 95 //#define MSG_UNEQUIP 95
#define MSG_CARD_TARGET 96 #define MSG_CARD_TARGET 96
#define MSG_CANCEL_TARGET 97 #define MSG_CANCEL_TARGET 97
#define MSG_PAY_LPCOST 100 #define MSG_PAY_LPCOST 100
...@@ -307,9 +327,9 @@ struct card_sort { ...@@ -307,9 +327,9 @@ struct card_sort {
#define MSG_DAMAGE_STEP_START 113 #define MSG_DAMAGE_STEP_START 113
#define MSG_DAMAGE_STEP_END 114 #define MSG_DAMAGE_STEP_END 114
#define MSG_MISSED_EFFECT 120 #define MSG_MISSED_EFFECT 120
#define MSG_BE_CHAIN_TARGET 121 //#define MSG_BE_CHAIN_TARGET 121
#define MSG_CREATE_RELATION 122 //#define MSG_CREATE_RELATION 122
#define MSG_RELEASE_RELATION 123 //#define MSG_RELEASE_RELATION 123
#define MSG_TOSS_COIN 130 #define MSG_TOSS_COIN 130
#define MSG_TOSS_DICE 131 #define MSG_TOSS_DICE 131
#define MSG_ROCK_PAPER_SCISSORS 132 #define MSG_ROCK_PAPER_SCISSORS 132
...@@ -320,9 +340,9 @@ struct card_sort { ...@@ -320,9 +340,9 @@ struct card_sort {
#define MSG_ANNOUNCE_NUMBER 143 #define MSG_ANNOUNCE_NUMBER 143
#define MSG_CARD_HINT 160 #define MSG_CARD_HINT 160
#define MSG_TAG_SWAP 161 #define MSG_TAG_SWAP 161
#define MSG_RELOAD_FIELD 162 // Debug.ReloadFieldEnd() #define MSG_RELOAD_FIELD 162 // Debug.ReloadFieldEnd() or query_field_info()
#define MSG_AI_NAME 163 #define MSG_AI_NAME 163 // Debug.AIName()
#define MSG_SHOW_HINT 164 #define MSG_SHOW_HINT 164 // Debug.ShowHint()
#define MSG_PLAYER_HINT 165 #define MSG_PLAYER_HINT 165
#define MSG_MATCH_KILL 170 #define MSG_MATCH_KILL 170
#define MSG_CUSTOM_MSG 180 #define MSG_CUSTOM_MSG 180
...@@ -389,12 +409,13 @@ struct card_sort { ...@@ -389,12 +409,13 @@ struct card_sort {
//Options //Options
#define DUEL_TEST_MODE 0x01 #define DUEL_TEST_MODE 0x01
#define DUEL_ATTACK_FIRST_TURN 0x02 #define DUEL_ATTACK_FIRST_TURN 0x02
#define DUEL_OLD_REPLAY 0x04 //#define DUEL_OLD_REPLAY 0x04
#define DUEL_OBSOLETE_RULING 0x08 #define DUEL_OBSOLETE_RULING 0x08
#define DUEL_PSEUDO_SHUFFLE 0x10 #define DUEL_PSEUDO_SHUFFLE 0x10
#define DUEL_TAG_MODE 0x20 #define DUEL_TAG_MODE 0x20
#define DUEL_SIMPLE_AI 0x40 #define DUEL_SIMPLE_AI 0x40
#define DUEL_RETURN_DECK_TOP 0x80 #define DUEL_RETURN_DECK_TOP 0x80
#define DUEL_REVEAL_DECK_SEQ 0x100
//Activity //Activity
#define ACTIVITY_SUMMON 1 #define ACTIVITY_SUMMON 1
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Author: Argon * Author: Argon
*/ */
#include <cstring>
#include "duel.h" #include "duel.h"
#include "interpreter.h" #include "interpreter.h"
#include "field.h" #include "field.h"
...@@ -12,12 +13,16 @@ ...@@ -12,12 +13,16 @@
#include "effect.h" #include "effect.h"
#include "group.h" #include "group.h"
#include "ocgapi.h" #include "ocgapi.h"
#include "buffer.h"
duel::duel() { duel::duel() {
lua = new interpreter(this); lua = new interpreter(this);
game_field = new field(this); game_field = new field(this);
game_field->temp_card = new_card(0); game_field->temp_card = new_card(TEMP_CARD_ID);
clear_buffer(); message_buffer.reserve(SIZE_MESSAGE_BUFFER);
#ifdef _WIN32
_set_error_mode(_OUT_TO_MSGBOX);
#endif // _WIN32
} }
duel::~duel() { duel::~duel() {
for(auto& pcard : cards) for(auto& pcard : cards)
...@@ -40,16 +45,17 @@ void duel::clear() { ...@@ -40,16 +45,17 @@ void duel::clear() {
cards.clear(); cards.clear();
groups.clear(); groups.clear();
effects.clear(); effects.clear();
assumes.clear();
sgroups.clear();
uncopy.clear();
game_field = new field(this); game_field = new field(this);
game_field->temp_card = new_card(0); game_field->temp_card = new_card(TEMP_CARD_ID);
} }
card* duel::new_card(uint32 code) { card* duel::new_card(uint32_t code) {
card* pcard = new card(this); card* pcard = new card(this);
cards.insert(pcard); cards.insert(pcard);
if(code) if (code != TEMP_CARD_ID)
::read_card(code, &(pcard->data)); ::read_card(code, &(pcard->data));
else
pcard->data.clear();
pcard->data.code = code; pcard->data.code = code;
lua->register_card(pcard); lua->register_card(pcard);
return pcard; return pcard;
...@@ -94,13 +100,15 @@ void duel::delete_effect(effect* peffect) { ...@@ -94,13 +100,15 @@ void duel::delete_effect(effect* peffect) {
effects.erase(peffect); effects.erase(peffect);
delete peffect; delete peffect;
} }
int32 duel::read_buffer(byte* buf) { int32_t duel::read_buffer(byte* buf) {
std::memcpy(buf, buffer, bufferlen); auto size = buffer_size();
return bufferlen; if (size)
std::memcpy(buf, message_buffer.data(), size);
return (int32_t)size;
} }
void duel::release_script_group() { void duel::release_script_group() {
for(auto& pgroup : sgroups) { for(auto& pgroup : sgroups) {
if(pgroup->is_readonly == 0) { if(pgroup->is_readonly == GTYPE_DEFAULT) {
lua->unregister_group(pgroup); lua->unregister_group(pgroup);
groups.erase(pgroup); groups.erase(pgroup);
delete pgroup; delete pgroup;
...@@ -113,36 +121,29 @@ void duel::restore_assumes() { ...@@ -113,36 +121,29 @@ void duel::restore_assumes() {
pcard->assume_type = 0; pcard->assume_type = 0;
assumes.clear(); assumes.clear();
} }
void duel::write_buffer32(uint32 value) { void duel::write_buffer(const void* data, int size) {
std::memcpy(bufferp, &value, sizeof(value)); vector_write_block(message_buffer, data, size);
bufferp += 4; }
bufferlen += 4; void duel::write_buffer32(uint32_t value) {
vector_write<uint32_t>(message_buffer, value);
} }
void duel::write_buffer16(uint16 value) { void duel::write_buffer16(uint16_t value) {
std::memcpy(bufferp, &value, sizeof(value)); vector_write<uint16_t>(message_buffer, value);
bufferp += 2;
bufferlen += 2;
} }
void duel::write_buffer8(uint8 value) { void duel::write_buffer8(uint8_t value) {
std::memcpy(bufferp, &value, sizeof(value)); vector_write<unsigned char>(message_buffer, value);
bufferp += 1;
bufferlen += 1;
} }
void duel::clear_buffer() { void duel::clear_buffer() {
bufferlen = 0; message_buffer.clear();
bufferp = buffer;
} }
void duel::set_responsei(uint32 resp) { void duel::set_responsei(uint32_t resp) {
game_field->returns.ivalue[0] = resp; game_field->returns.ivalue[0] = resp;
} }
void duel::set_responseb(byte* resp) { void duel::set_responseb(byte* resp) {
std::memcpy(game_field->returns.bvalue, resp, 64); std::memcpy(game_field->returns.bvalue, resp, SIZE_RETURN_VALUE);
} }
int32 duel::get_next_integer(int32 l, int32 h) { int32_t duel::get_next_integer(int32_t l, int32_t h) {
if (game_field->core.duel_options & DUEL_OLD_REPLAY) { if (rng_version == 1)
return random.get_random_integer_old(l, h); return random.get_random_integer_v1(l, h);
} return random.get_random_integer_v2(l, h);
else {
return random.get_random_integer(l, h);
}
} }
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
#define DUEL_H_ #define DUEL_H_
#include "common.h" #include "common.h"
#include "sort.h"
#include "mtrandom.h" #include "mtrandom.h"
#include <set> #include <set>
#include <unordered_set> #include <unordered_set>
#include <vector>
class card; class card;
class group; class group;
...@@ -19,16 +21,17 @@ class effect; ...@@ -19,16 +21,17 @@ class effect;
class field; class field;
class interpreter; class interpreter;
using card_set = std::set<card*, card_sort>;
class duel { class duel {
public: public:
using card_set = std::set<card*, card_sort>; char strbuffer[256]{};
char strbuffer[256]; int32_t rng_version{ 2 };
byte buffer[0x1000];
uint32 bufferlen;
byte* bufferp;
interpreter* lua; interpreter* lua;
field* game_field; field* game_field;
mt19937 random; mtrandom random;
std::vector<byte> message_buffer;
std::unordered_set<card*> cards; std::unordered_set<card*> cards;
std::unordered_set<card*> assumes; std::unordered_set<card*> assumes;
std::unordered_set<group*> groups; std::unordered_set<group*> groups;
...@@ -40,7 +43,10 @@ public: ...@@ -40,7 +43,10 @@ public:
~duel(); ~duel();
void clear(); void clear();
card* new_card(uint32 code); uint32_t buffer_size() const {
return (uint32_t)message_buffer.size() & PROCESSOR_BUFFER_LEN;
}
card* new_card(uint32_t code);
group* new_group(); group* new_group();
group* new_group(card* pcard); group* new_group(card* pcard);
group* new_group(const card_set& cset); group* new_group(const card_set& cset);
...@@ -50,14 +56,15 @@ public: ...@@ -50,14 +56,15 @@ public:
void delete_effect(effect* peffect); void delete_effect(effect* peffect);
void release_script_group(); void release_script_group();
void restore_assumes(); void restore_assumes();
int32 read_buffer(byte* buf); int32_t read_buffer(byte* buf);
void write_buffer32(uint32 value); void write_buffer(const void* data, int size);
void write_buffer16(uint16 value); void write_buffer32(uint32_t value);
void write_buffer8(uint8 value); void write_buffer16(uint16_t value);
void write_buffer8(uint8_t value);
void clear_buffer(); void clear_buffer();
void set_responsei(uint32 resp); void set_responsei(uint32_t resp);
void set_responseb(byte* resp); void set_responseb(byte* resp);
int32 get_next_integer(int32 l, int32 h); int32_t get_next_integer(int32_t l, int32_t h);
private: private:
group* register_group(group* pgroup); group* register_group(group* pgroup);
}; };
......
This diff is collapsed.
This diff is collapsed.
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
#ifndef EFFECTSET_H_ #ifndef EFFECTSET_H_
#define EFFECTSET_H_ #define EFFECTSET_H_
#include <stdlib.h>
#include <array>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
...@@ -17,100 +15,7 @@ class effect; ...@@ -17,100 +15,7 @@ class effect;
bool effect_sort_id(const effect* e1, const effect* e2); bool effect_sort_id(const effect* e1, const effect* e2);
struct effect_set { using effect_set = std::vector<effect*>;
effect_set() using effect_set_v = effect_set;
: count(0), container{ nullptr } {}
void add_item(effect* peffect) {
if(count >= 64) return;
container[count++] = peffect;
}
void remove_item(int index) {
if(index >= count)
return;
if(index == count - 1) {
count--;
return;
}
for(int i = index; i < count - 1; ++i)
container[i] = container[i + 1];
count--;
}
void clear() {
count = 0;
}
int size() const {
return count;
}
void sort() {
if(count < 2)
return;
std::sort(container.begin(), container.begin() + count, effect_sort_id);
}
effect* const& get_last() const {
return container[count - 1];
}
effect*& get_last() {
return container[count - 1];
}
effect* const& operator[] (int index) const {
return container[index];
}
effect*& operator[] (int index) {
return container[index];
}
effect* const& at(int index) const {
return container[index];
}
effect*& at(int index) {
return container[index];
}
private:
std::array<effect*, 64> container;
int count;
};
struct effect_set_v {
effect_set_v() {}
void add_item(effect* peffect) {
container.push_back(peffect);
}
void remove_item(int index) {
if(index >= (int)container.size())
return;
container.erase(container.begin() + index);
}
void clear() {
container.clear();
}
int size() const {
return (int)container.size();
}
void sort() {
int count = (int)container.size();
if(count < 2)
return;
std::sort(container.begin(), container.begin() + count, effect_sort_id);
}
effect* const& get_last() const {
return container.back();
}
effect*& get_last() {
return container.back();
}
effect* const& operator[] (int index) const {
return container[index];
}
effect*& operator[] (int index) {
return container[index];
}
effect* const& at(int index) const {
return container[index];
}
effect*& at(int index) {
return container[index];
}
private:
std::vector<effect*> container;
};
#endif //EFFECTSET_H_ #endif //EFFECTSET_H_
This diff is collapsed.
This diff is collapsed.
...@@ -10,21 +10,15 @@ ...@@ -10,21 +10,15 @@
#include "duel.h" #include "duel.h"
group::group(duel* pd) { group::group(duel* pd) {
ref_handle = 0;
pduel = pd; pduel = pd;
is_readonly = FALSE;
it = container.begin(); it = container.begin();
} }
group::group(duel* pd, card* pcard) { group::group(duel* pd, card* pcard) {
container.insert(pcard); container.insert(pcard);
ref_handle = 0;
pduel = pd; pduel = pd;
is_readonly = FALSE;
it = container.begin(); it = container.begin();
} }
group::group(duel* pd, const card_set& cset): container(cset) { group::group(duel* pd, const card_set& cset): container(cset) {
ref_handle = 0;
pduel = pd; pduel = pd;
is_readonly = FALSE;
it = container.begin(); it = container.begin();
} }
...@@ -9,22 +9,29 @@ ...@@ -9,22 +9,29 @@
#define GROUP_H_ #define GROUP_H_
#include "common.h" #include "common.h"
#include "sort.h"
#include <set> #include <set>
#include <list> #include <list>
class card; class card;
class duel; class duel;
class group { using card_set = std::set<card*, card_sort>;
constexpr uint32_t GTYPE_DEFAULT = 0;
constexpr uint32_t GTYPE_READ_ONLY = 1;
constexpr uint32_t GTYPE_KEEP_ALIVE = 2;
class alignas(8) group {
public: public:
using card_set = std::set<card*, card_sort>; int32_t ref_handle{ 0 };
int32 ref_handle; uint32_t is_readonly{ GTYPE_DEFAULT };
duel* pduel; duel* pduel;
card_set container; card_set container;
card_set::iterator it; card_set::iterator it;
uint32 is_readonly; bool is_iterator_dirty{ true };
inline bool has_card(card* c) { bool has_card(card* c) {
return container.find(c) != container.end(); return container.find(c) != container.end();
} }
......
This diff is collapsed.
...@@ -8,25 +8,40 @@ ...@@ -8,25 +8,40 @@
#ifndef INTERPRETER_H_ #ifndef INTERPRETER_H_
#define INTERPRETER_H_ #define INTERPRETER_H_
#include "lua.h" #include <lua.h>
#include "lauxlib.h" #include <lauxlib.h>
#include "lualib.h" #include <lualib.h>
#include "common.h" #include "common.h"
#include <unordered_map> #include <unordered_map>
#include <list> #include <list>
#include <vector> #include <vector>
#include <cstdio> #include <cstdio>
#include <cstring>
class card; class card;
struct card_data;
class effect; class effect;
class group; class group;
class duel; class duel;
enum LuaParamType : int32_t {
PARAM_TYPE_INT = 0x01,
PARAM_TYPE_STRING = 0x02,
PARAM_TYPE_CARD = 0x04,
PARAM_TYPE_GROUP = 0x08,
PARAM_TYPE_EFFECT = 0x10,
PARAM_TYPE_FUNCTION = 0x20,
PARAM_TYPE_BOOLEAN = 0x40,
PARAM_TYPE_INDEX = 0x80,
};
class interpreter { class interpreter {
public: public:
using coroutine_map = std::unordered_map<int32, lua_State*>; union lua_param {
using param_list = std::list<std::pair<void*, uint32>>; void* ptr;
int32_t integer;
};
using coroutine_map = std::unordered_map<int32_t, std::pair<lua_State*, int32_t>>;
using param_list = std::list<std::pair<lua_param, LuaParamType>>;
duel* pduel; duel* pduel;
char msgbuf[64]; char msgbuf[64];
...@@ -35,41 +50,42 @@ public: ...@@ -35,41 +50,42 @@ public:
param_list params; param_list params;
param_list resumes; param_list resumes;
coroutine_map coroutines; coroutine_map coroutines;
int32 no_action; int32_t no_action;
int32 call_depth; int32_t call_depth;
explicit interpreter(duel* pd); explicit interpreter(duel* pd);
~interpreter(); ~interpreter();
int32 register_card(card* pcard); void register_card(card* pcard);
void register_effect(effect* peffect); void register_effect(effect* peffect);
void unregister_effect(effect* peffect); void unregister_effect(effect* peffect);
void register_group(group* pgroup); void register_group(group* pgroup);
void unregister_group(group* pgroup); void unregister_group(group* pgroup);
int32 load_script(const char* script_name); int32_t load_script(const char* script_name);
int32 load_card_script(uint32 code); int32_t load_card_script(uint32_t code);
void add_param(void* param, int32 type, bool front = false); void add_param(void* param, LuaParamType type, bool front = false);
void add_param(int32 param, int32 type, bool front = false); void add_param(int32_t param, LuaParamType type, bool front = false);
void push_param(lua_State* L, bool is_coroutine = false); void push_param(lua_State* L, bool is_coroutine = false);
int32 call_function(int32 f, uint32 param_count, int32 ret_count); int32_t call_function(int32_t f, uint32_t param_count, int32_t ret_count);
int32 call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count); int32_t call_card_function(card* pcard, const char* f, uint32_t param_count, int32_t ret_count);
int32 call_code_function(uint32 code, const char* f, uint32 param_count, int32 ret_count); int32_t call_code_function(uint32_t code, const char* f, uint32_t param_count, int32_t ret_count);
int32 check_condition(int32 f, uint32 param_count); int32_t check_condition(int32_t f, uint32_t param_count);
int32 check_matching(card* pcard, int32 findex, int32 extraargs); int32_t check_filter(lua_State* L, card* pcard, int32_t findex, int32_t extraargs);
int32 get_operation_value(card* pcard, int32 findex, int32 extraargs); int32_t get_operation_value(card* pcard, int32_t findex, int32_t extraargs);
int32 get_function_value(int32 f, uint32 param_count); int32_t get_function_value(int32_t f, uint32_t param_count);
int32 get_function_value(int32 f, uint32 param_count, std::vector<int32>* result); int32_t get_function_value(int32_t f, uint32_t param_count, std::vector<lua_Integer>& result);
int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step); int32_t call_coroutine(int32_t f, uint32_t param_count, int32_t* yield_value, uint16_t step);
int32 clone_function_ref(int32 func_ref); int32_t clone_function_ref(int32_t func_ref);
void* get_ref_object(int32 ref_handler); void* get_ref_object(int32_t ref_handler);
static void card2value(lua_State* L, card* pcard); static void card2value(lua_State* L, card* pcard);
static void group2value(lua_State* L, group* pgroup); static void group2value(lua_State* L, group* pgroup);
static void effect2value(lua_State* L, effect* peffect); static void effect2value(lua_State* L, effect* peffect);
static void function2value(lua_State* L, int32 pointer); static void function2value(lua_State* L, int32_t func_ref);
static int32 get_function_handle(lua_State* L, int32 index); static int32_t get_function_handle(lua_State* L, int32_t index);
static duel* get_duel_info(lua_State* L); static duel* get_duel_info(lua_State* L);
static bool is_load_script(const card_data& data);
template <size_t N, typename... TR> template <size_t N, typename... TR>
static int sprintf(char (&buffer)[N], const char* format, TR... args) { static int sprintf(char (&buffer)[N], const char* format, TR... args) {
...@@ -77,15 +93,6 @@ public: ...@@ -77,15 +93,6 @@ public:
} }
}; };
#define PARAM_TYPE_INT 0x01
#define PARAM_TYPE_STRING 0x02
#define PARAM_TYPE_CARD 0x04
#define PARAM_TYPE_GROUP 0x08
#define PARAM_TYPE_EFFECT 0x10
#define PARAM_TYPE_FUNCTION 0x20
#define PARAM_TYPE_BOOLEAN 0x40
#define PARAM_TYPE_INDEX 0x80
#define COROUTINE_FINISH 1 #define COROUTINE_FINISH 1
#define COROUTINE_YIELD 2 #define COROUTINE_YIELD 2
#define COROUTINE_ERROR 3 #define COROUTINE_ERROR 3
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -9,61 +9,77 @@ ...@@ -9,61 +9,77 @@
#define MTRANDOM_H_ #define MTRANDOM_H_
#include <random> #include <random>
#include <vector>
#include <utility>
class mt19937 { class mtrandom {
public: public:
const unsigned int rand_max; const unsigned int rand_max{ std::mt19937::max() };
mt19937() : mtrandom() :
rng(), rand_max((rng.max)()) {} rng() {}
explicit mt19937(unsigned int seed) : mtrandom(uint32_t seq[], size_t len) {
rng(seed), rand_max((rng.max)()) {} std::seed_seq q(seq, seq + len);
rng.seed(q);
}
explicit mtrandom(uint_fast32_t value) :
rng(value) {}
mtrandom(std::seed_seq& q) :
rng(q) {}
mtrandom(const mtrandom& other) = delete;
void operator=(const mtrandom& other) = delete;
// mersenne_twister_engine // mersenne_twister_engine
void reset(unsigned int seed) { void seed(uint32_t seq[], size_t len) {
rng.seed(seed); std::seed_seq q(seq, seq + len);
rng.seed(q);
}
void seed(uint_fast32_t value) {
rng.seed(value);
} }
unsigned int rand() { void seed(std::seed_seq& q) {
rng.seed(q);
}
uint_fast32_t rand() {
return rng(); return rng();
} }
void discard(unsigned long long z) {
rng.discard(z);
}
// uniform_int_distribution // old vesion, discard too many numbers
int get_random_integer(int l, int h) { int get_random_integer_v1(int l, int h) {
unsigned int range = (unsigned int)(h - l + 1); uint32_t range = (h - l + 1);
unsigned int secureMax = rand_max - rand_max % range; uint32_t secureMax = rand_max - rand_max % range;
unsigned int x; uint_fast32_t x;
do { do {
x = rng(); x = rng();
} while (x >= secureMax); } while (x >= secureMax);
return (int)(l + x % range); return l + (int)(x % range);
}
int get_random_integer_old(int l, int h) {
int result = (int)((double)rng() / rand_max * ((double)h - l + 1)) + l;
if (result > h)
result = h;
return result;
} }
// Fisher-Yates shuffle v[a]~v[b] // N % k == (N - k) % k, discard the leftmost numbers
template<typename T> int get_random_integer_v2(int l, int h) {
void shuffle_vector(std::vector<T>& v, int a = -1, int b = -1) { uint32_t range = (h - l + 1);
if (a < 0) uint32_t bound = -range % range;
a = 0; auto x = rng();
if (b < 0) while (x < bound) {
b = (int)v.size() - 1; x = rng();
for (int i = a; i < b; ++i) {
int r = get_random_integer(i, b);
std::swap(v[i], v[r]);
} }
return l + (int)(x % range);
} }
// Fisher-Yates shuffle [first, last)
template<typename T> template<typename T>
void shuffle_vector_old(std::vector<T>& v, int a = -1, int b = -1) { void shuffle_vector(std::vector<T>& v, int first = 0, int last = INT32_MAX, int version = 2) {
if (a < 0) if ((size_t)last > v.size())
a = 0; last = v.size();
if (b < 0) auto distribution = &mtrandom::get_random_integer_v2;
b = (int)v.size() - 1; if (version == 1)
for (int i = a; i < b; ++i) { distribution = &mtrandom::get_random_integer_v1;
int r = get_random_integer_old(i, b); for (int i = first; i < last - 1; ++i) {
int r = (this->*distribution)(i, last - 1);
std::swap(v[i], v[r]); std::swap(v[i], v[r]);
} }
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
project "lua"
kind "StaticLib"
compileas "C++"
files { "src/*.c", "src/*.h" }
removefiles { "src/lua.c", "src/luac.c", "src/linit.c", "src/onelua.c" }
filter "configurations:Debug"
defines { "LUA_USE_APICHECK" }
filter "system:bsd"
defines { "LUA_USE_POSIX" }
filter "system:macosx"
defines { "LUA_USE_MACOSX" }
filter "system:linux"
defines { "LUA_USE_LINUX" }
project "ocgcore" project "ocgcore"
kind "StaticLib" kind "StaticLib"
cppdialect "C++14"
files { "*.cpp", "*.h" } files { "*.cpp", "*.h" }
links { LUA_LIB_NAME }
if BUILD_LUA then if BUILD_LUA then
includedirs { "../lua/src" } includedirs { "../lua/src" }
else else
includedirs { LUA_INCLUDE_DIR } includedirs { LUA_INCLUDE_DIR }
libdirs { LUA_LIB_DIR }
end end
filter "not action:vs*"
buildoptions { "-std=c++14" }
filter "system:bsd" filter "system:bsd"
defines { "LUA_USE_POSIX" } defines { "LUA_USE_POSIX" }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef SORT_H_
#define SORT_H_
class card;
struct card_sort {
bool operator()(card* const& c1, card* const& c2) const;
};
#endif /* SORT_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment