/// <summary> /// Gets all currently available chessboards. Chessboards are ordered by their id, indicating when they were created. (<see cref="ChessBoard.Id"/>). /// </summary> /// <returns>A list of <see cref="ChessBoard"/>, each representing a single chessboard.</returns> public List <ChessBoard> GetChessBoards() { var len = this.MemLocChessArraySize.GetValue(); var bytesToRead = (uint)(len * ChessBoardMemory.structSize); var boardLoc = this.MemLocChessArrayPointer.GetValue(); var bytes = KernelMethods.ReadMemory(GetGameHandle(), boardLoc, bytesToRead, out uint bytesRead); if (bytesToRead != bytesRead) { throw new Exception("Not all bytes have been read!"); } var chunks = new List <byte[]>(); for (int i = 0; i < len; i++) { var dest = new byte[ChessBoardMemory.structSize]; Array.Copy(bytes, i * ChessBoardMemory.structSize, dest, 0, ChessBoardMemory.structSize); chunks.Add(dest); } var cbms = chunks.Select(x => ChessBoardMemory.ParseFromByteArray(x)).ToList(); var chessboardSize = GetChessBoardSize(); var cbs = cbms.Select(x => new ChessBoard(x, chessboardSize.Width, chessboardSize.Height)).ToList(); return(cbs); }
/// <summary> /// Load a JVM dll to use as java server for the java vm calls /// Notes : /// - the previous library is released if one was already launched /// - Alledgedly, a library previously load is prioritized /// https://docs.microsoft.com/fr-fr/windows/win32/dlls/dynamic-link-library-search-order?redirectedfrom=MSDN /// </summary> /// <param name="jvm_dll_path"></param> public static void loadAssembly(string jvm_dll_path) { if (_dllPtr != IntPtr.Zero) { KernelMethods.FreeLibrary(_dllPtr); } _dllPtr = KernelMethods.LoadLibrary(jvm_dll_path); // Just in case : // according to DLL search order, previously loaded DLL are prioritized // But just in case, i also set the dll search directory to ensure bool dllDirValid = KernelMethods.SetDllDirectory(Path.GetDirectoryName(jvm_dll_path)); if (_dllPtr == IntPtr.Zero || !dllDirValid) { throw new Exception($"An error occured while loading {jvm_dll_path}"); } }
public void ModifyChessBoards(Func <ChessBoard, ChessBoard> lambda) { var len = this.MemLocChessArrayElementCount.GetValue(); var bytesToRead = (uint)(len * ChessBoardMemory.structSize); var boardLoc = this.MemLocChessArrayPointer.GetValue(); var bytes = KernelMethods.ReadMemory(GetGameHandle(), boardLoc, bytesToRead, out uint bytesRead); if (bytesToRead != bytesRead) { throw new Exception("Not all bytes have been read!"); } var size = GetChessBoardSize(); for (int i = 0; i < len; i++) { var dest = new byte[ChessBoardMemory.structSize]; Array.Copy(bytes, i * ChessBoardMemory.structSize, dest, 0, ChessBoardMemory.structSize); var board = ChessBoardMemory.ParseFromByteArray(dest); var modifiedBoard = lambda.Invoke(new ChessBoard(board, size.Width, size.Height)); var newBytes = ChessBoardMemory.ToByteArray(modifiedBoard.cbm); if (newBytes.Length != ChessBoardMemory.structSize) { throw new Exception("For some reason the modified ChessBaordMemory struct is smaller than the original which is not allowed"); } var updateRequired = false; for (int j = 0; j < newBytes.Length; j++) { if (newBytes[j] != bytes[i * ChessBoardMemory.structSize + j]) // if any of the bytes changed { updateRequired = true; break; } } // resolve deltas, to not overwrite potentially modified data -- experimental but seems to work, but doesnt solve the problem where an AI gets stuck // if we swap pieces while the ai is thinking if (updateRequired) { // var byteDelta = newBytes.Select((x, i) => x == bytes[i] ? (byte?)null : x).ToArray(); var lengths = new List <(int, int)>(); // tuples of start index, length int currStartIndex = -1; for (int bi = 0; bi < newBytes.Length; bi++) { var byteDiffers = bytes[bi] != newBytes[bi]; if (currStartIndex == -1) // not currently in a group { if (byteDiffers) { currStartIndex = bi; } } else { if (!byteDiffers) { lengths.Add((currStartIndex, bi - currStartIndex)); currStartIndex = -1; } } } if (currStartIndex != -1) { lengths.Add((currStartIndex, newBytes.Length - currStartIndex)); } foreach (var(startindex, length) in lengths) { KernelMethods.WriteMemory(GetGameHandle(), boardLoc + i * ChessBoardMemory.structSize + startindex, newBytes.Skip(startindex).Take(length).ToArray()); } } } }