Phase 1A: rob-twophase solver integration — Windows build validated
- Added rob-twophase C++ source to Private/ThirdParty/rob-twophase/ - Created HyperTwistSolverLibrary Blueprint function library - Fixed UE macro conflicts: check→ValidateCube, UF→UF_EDGE - Added msvc_compat.h for missing POSIX ffs/ffsll on Windows - Replaced unistd.h with direct.h/io.h for _chdir, access - Fixed C4700 uninitialized qt_skip1 in solve.cpp - Updated Build.cs with ThirdParty include paths - Removed WebBrowser plugin dependency from .uproject - Build: 5 actions, 38.87s, exit code 0
This commit is contained in:
parent
4359e572c9
commit
15bb3d9039
11 changed files with 60 additions and 32 deletions
|
|
@ -4,6 +4,13 @@
|
|||
#include "Misc/Paths.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#include <direct.h>
|
||||
#define chdir _chdir
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "ThirdParty/rob-twophase/face.h"
|
||||
#include "ThirdParty/rob-twophase/move.h"
|
||||
#include "ThirdParty/rob-twophase/cubie.h"
|
||||
|
|
@ -26,7 +33,7 @@ static void DoInitSolver()
|
|||
|
||||
if (FPaths::DirectoryExists(SavedDir))
|
||||
{
|
||||
FPlatformProcess::SetCurrentWorkingDirectory(*SavedDir);
|
||||
chdir(TCHAR_TO_UTF8(*SavedDir));
|
||||
}
|
||||
|
||||
face::init();
|
||||
|
|
@ -36,7 +43,7 @@ static void DoInitSolver()
|
|||
prun::init(true); // true = try to load tables, generate if missing
|
||||
|
||||
// Restore working directory
|
||||
FPlatformProcess::SetCurrentWorkingDirectory(*OriginalDir);
|
||||
chdir(TCHAR_TO_UTF8(*OriginalDir));
|
||||
|
||||
bSolverInitialized = true;
|
||||
}
|
||||
|
|
@ -76,7 +83,7 @@ TArray<FString> UHyperTwistSolverLibrary::SolveClassicState(
|
|||
return Result;
|
||||
}
|
||||
|
||||
if (cubie::check(Cube) != 0)
|
||||
if (cubie::check_cube(Cube) != 0)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("HyperTwistSolver: Cube state is not solvable"));
|
||||
return Result;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "msvc_compat.h"
|
||||
#include "coord.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ namespace cubie {
|
|||
into.eori[i] = c.eori[into.eperm[i]];
|
||||
}
|
||||
|
||||
int check(const cube& c) {
|
||||
int check_cube(const cube& c) {
|
||||
bool corners[corner::COUNT] = {};
|
||||
int cori_sum = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace cubie {
|
|||
const int COUNT = 12;
|
||||
|
||||
const int UR = 0;
|
||||
const int UF = 1;
|
||||
const int UF_EDGE = 1;
|
||||
const int UL = 2;
|
||||
const int UB = 3;
|
||||
const int DR = 4;
|
||||
|
|
@ -61,7 +61,7 @@ namespace cubie {
|
|||
|
||||
const cube SOLVED_CUBE = {
|
||||
{URF, UFL, ULB, UBR, DFR, DLF, DBL, DRB},
|
||||
{UR, UF, UL, UB, DR, DF, DL, DB, FR, FL, BL, BR},
|
||||
{UR, UF_EDGE, UL, UB, DR, DF, DL, DB, FR, FL, BL, BR},
|
||||
{}, {}
|
||||
}; // cubie-cube in solved state
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ namespace cubie {
|
|||
void mul(const cube& c1, const cube& c2, cube& into); // fully multiply two cubes
|
||||
void inv(const cube& c, cube& into); // compute the inverse cube
|
||||
void shuffle(cube& c); // generate a uniformly random cube
|
||||
int check(const cube& c); // check a cube for being solvable
|
||||
int check_cube(const cube& c); // check a cube for being solvable
|
||||
|
||||
bool operator==(const cube& c1, const cube& c2);
|
||||
bool operator!=(const cube& c1, const cube& c2);
|
||||
|
|
|
|||
|
|
@ -98,33 +98,33 @@ namespace move {
|
|||
cubie::cube fcubes[] = {
|
||||
{ // U
|
||||
{UBR, URF, UFL, ULB, DFR, DLF, DBL, DRB},
|
||||
{UB, UR, UF, UL, DR, DF, DL, DB, FR, FL, BL, BR},
|
||||
{UB, UR, UF_EDGE, UL, DR, DF, DL, DB, FR, FL, BL, BR},
|
||||
{}, {}
|
||||
},
|
||||
{ // D
|
||||
{URF, UFL, ULB, UBR, DLF, DBL, DRB, DFR},
|
||||
{UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
|
||||
{UR, UF_EDGE, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
|
||||
{}, {}
|
||||
},
|
||||
{ // R
|
||||
{DFR, UFL, ULB, URF, DRB, DLF, DBL, UBR},
|
||||
{FR, UF, UL, UB, BR, DF, DL, DB, DR, FL, BL, UR},
|
||||
{FR, UF_EDGE, UL, UB, BR, DF, DL, DB, DR, FL, BL, UR},
|
||||
{2, 0, 0, 1, 1, 0, 0, 2}, {}
|
||||
},
|
||||
{ // L
|
||||
{URF, ULB, DBL, UBR, DFR, UFL, DLF, DRB},
|
||||
{UR, UF, BL, UB, DR, DF, FL, DB, FR, UL, DL, BR},
|
||||
{UR, UF_EDGE, BL, UB, DR, DF, FL, DB, FR, UL, DL, BR},
|
||||
{0, 1, 2, 0, 0, 2, 1, 0}, {}
|
||||
},
|
||||
{ // F
|
||||
{UFL, DLF, ULB, UBR, URF, DFR, DBL, DRB},
|
||||
{UR, FL, UL, UB, DR, FR, DL, DB, UF, DF, BL, BR},
|
||||
{UR, FL, UL, UB, DR, FR, DL, DB, UF_EDGE, DF, BL, BR},
|
||||
{1, 2, 0, 0, 2, 1, 0, 0},
|
||||
{0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0}
|
||||
},
|
||||
{ // B
|
||||
{URF, UFL, UBR, DRB, DFR, DLF, ULB, DBL},
|
||||
{UR, UF, UL, BR, DR, DF, DL, BL, FR, FL, UB, DB},
|
||||
{UR, UF_EDGE, UL, BR, DR, DF, DL, BL, FR, FL, UB, DB},
|
||||
{0, 0, 1, 2, 0, 0, 2, 1},
|
||||
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1}
|
||||
}
|
||||
|
|
|
|||
21
UnrealHyperTwist/Source/UnrealHyperTwist/Private/ThirdParty/rob-twophase/msvc_compat.h
vendored
Normal file
21
UnrealHyperTwist/Source/UnrealHyperTwist/Private/ThirdParty/rob-twophase/msvc_compat.h
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
|
||||
inline int ffs(int x) {
|
||||
unsigned long index;
|
||||
if (_BitScanForward(&index, (unsigned long)x))
|
||||
return (int)index + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int ffsll(long long x) {
|
||||
unsigned long index;
|
||||
if (_BitScanForward64(&index, (unsigned __int64)x))
|
||||
return (int)index + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
#include "msvc_compat.h"
|
||||
#include "prun.h"
|
||||
|
||||
#include <bitset>
|
||||
|
|
@ -104,8 +105,8 @@ namespace prun {
|
|||
|
||||
remap[0][eff][mask] = ((mask1 & 1) ? 0 : ~(mask1 >> 1) & 0x7) << 6 * sym::eff_shift(eff);
|
||||
remap[1][eff][mask] = ((mask1 & 1) ? ~(mask1 >> 1) & 0x7 : 0x7) << 6 * sym::eff_shift(eff);
|
||||
remap[0][eff][mask] |= ((mask2 & 1) ? 0 : ~(mask2 >> 1) & 0x7) << 6 * sym::eff_shift(eff) + 3;
|
||||
remap[1][eff][mask] |= ((mask2 & 1) ? ~(mask2 >> 1) & 0x7 : 0x7) << 6 * sym::eff_shift(eff) + 3;
|
||||
remap[0][eff][mask] |= ((mask2 & 1) ? 0 : ~(mask2 >> 1) & 0x7) << (6 * sym::eff_shift(eff) + 3);
|
||||
remap[1][eff][mask] |= ((mask2 & 1) ? ~(mask2 >> 1) & 0x7 : 0x7) << (6 * sym::eff_shift(eff) + 3);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
@ -217,7 +218,7 @@ namespace prun {
|
|||
int tmp = 0;
|
||||
for (int i = (ax + 1) * (bits_per_ax - 1) - 1; i >= ax * (bits_per_ax - 1); i--)
|
||||
tmp = (tmp | (away ? deltas[i] : deltas[i] + 1)) << 1;
|
||||
tmp |= away;
|
||||
tmp |= (away ? 1 : 0);
|
||||
|
||||
prun = (prun << bits_per_ax) | tmp;
|
||||
}
|
||||
|
|
@ -252,7 +253,7 @@ namespace prun {
|
|||
count++;
|
||||
|
||||
for (move::mask moves = move::p2mask; moves; moves &= moves - 1) {
|
||||
int m = ffsll(moves) - 1;
|
||||
int m = ffsll((long long)moves) - 1;
|
||||
|
||||
int dist1 = dist + 1;
|
||||
#ifdef QT
|
||||
|
|
@ -310,7 +311,7 @@ namespace prun {
|
|||
int slice = coord::slice2_to_slice(slice2);
|
||||
|
||||
for (move::mask moves = move::p2mask; moves; moves &= moves - 1) {
|
||||
int m = ffsll(moves) - 1;
|
||||
int m = ffsll((long long)moves) - 1;
|
||||
|
||||
int dist1 = dist + 1;
|
||||
#ifdef QT
|
||||
|
|
@ -407,7 +408,7 @@ namespace prun {
|
|||
}
|
||||
|
||||
fclose(f);
|
||||
return err;
|
||||
return err != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "msvc_compat.h"
|
||||
#include "solve.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
|
@ -88,7 +89,7 @@ namespace solve {
|
|||
depth++;
|
||||
togo--;
|
||||
while (next) {
|
||||
int m = ffsll(next) - 1; // get rightmost move index (`ffsll()` uses 1-based indexing)
|
||||
int m = ffsll((long long)next) - 1; // get rightmost move index (`ffsll()` uses 1-based indexing)
|
||||
next &= next - 1;
|
||||
|
||||
int flip1 = coord::move_flip[flip][m];
|
||||
|
|
@ -103,7 +104,7 @@ namespace solve {
|
|||
moves[depth - 1] = m;
|
||||
|
||||
next1 &= move::p1mask & move::next[m];
|
||||
move::mask qt_skip1;
|
||||
move::mask qt_skip1 = 0;
|
||||
#ifdef QT // let `qt_skip` get completely optimized away when not in QT-mode
|
||||
qt_skip1 = move::qt_skip[m];
|
||||
next1 &= ~(qt_skip & qt_skip1);
|
||||
|
|
@ -135,7 +136,7 @@ namespace solve {
|
|||
}
|
||||
|
||||
while (next) {
|
||||
int m = ffsll(next) - 1; // get rightmost move index (`ffsll()` uses 1-based indexing)
|
||||
int m = ffsll((long long)next) - 1; // get rightmost move index (`ffsll()` uses 1-based indexing)
|
||||
next &= next - 1;
|
||||
|
||||
int slice1 = coord::move_edges4[slice][m];
|
||||
|
|
@ -181,7 +182,7 @@ namespace solve {
|
|||
) : n_threads(n_threads), tlim(tlim), n_sols(n_sols), max_len(max_len), n_splits(n_splits) {
|
||||
int tmp = (move::COUNT1 + n_splits - 1) / n_splits; // ceil to make sure that we always include all moves
|
||||
for (int i = 0; i < n_splits; i++)
|
||||
masks[i] = (move::mask(1) << tmp) - 1 << tmp * i;
|
||||
masks[i] = ((move::mask(1) << tmp) - 1) << (tmp * i);
|
||||
done = true; // make sure that the first `prepare()` will actually do something
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +291,7 @@ namespace solve {
|
|||
if (lenlim <= max_len) { // already found a solution that is short enough
|
||||
done = true; // end searching
|
||||
// Wake up timeout
|
||||
std::lock_guard<std::mutex> lock(tout_mtx);
|
||||
std::lock_guard<std::mutex> tout_lock(tout_mtx);
|
||||
tout_cvar.notify_one();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,22 +28,22 @@ namespace sym {
|
|||
|
||||
cubie::cube lr2 = {
|
||||
{UFL, URF, UBR, ULB, DLF, DFR, DRB, DBL},
|
||||
{UL, UF, UR, UB, DL, DF, DR, DB, FL, FR, BR, BL},
|
||||
{UL, UF_EDGE, UR, UB, DL, DF, DR, DB, FL, FR, BR, BL},
|
||||
{3, 3, 3, 3, 3, 3, 3, 3}, {} // special mirror ori
|
||||
};
|
||||
cubie::cube u4 = {
|
||||
{UBR, URF, UFL, ULB, DRB, DFR, DLF, DBL},
|
||||
{UB, UR, UF, UL, DB, DR, DF, DL, BR, FR, FL, BL},
|
||||
{UB, UR, UF_EDGE, UL, DB, DR, DF, DL, BR, FR, FL, BL},
|
||||
{}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
|
||||
};
|
||||
cubie::cube f2 = {
|
||||
{DLF, DFR, DRB, DBL, UFL, URF, UBR, ULB},
|
||||
{DL, DF, DR, DB, UL, UF, UR, UB, FL, FR, BR, BL},
|
||||
{DL, DF, DR, DB, UL, UF_EDGE, UR, UB, FL, FR, BR, BL},
|
||||
{}, {}
|
||||
};
|
||||
cubie::cube urf3 = {
|
||||
{URF, DFR, DLF, UFL, UBR, DRB, DBL, ULB},
|
||||
{UF, FR, DF, FL, UB, BR, DB, BL, UR, DR, DL, UL},
|
||||
{UF_EDGE, FR, DF, FL, UB, BR, DB, BL, UR, DR, DL, UL},
|
||||
{1, 2, 1, 2, 2, 1, 2, 1},
|
||||
{1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.IO;
|
||||
|
||||
public class UnrealHyperTwist : ModuleRules
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,10 +21,6 @@
|
|||
{
|
||||
"Name": "RemoteControl",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Name": "WebBrowser",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue