Simulation progress?.. (works like shit but at least something)
This commit is contained in:
parent
f7a08286f8
commit
836f533e3a
|
@ -3,6 +3,7 @@ import 'dart:developer' as developer;
|
|||
import 'dart:ffi';
|
||||
import 'dart:math';
|
||||
import 'package:logging/logging.dart' as logging;
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'dart:io';
|
||||
import 'tetrio_multiplayer_replay.dart';
|
||||
|
||||
|
@ -76,13 +77,64 @@ class HandlingHandler{
|
|||
}
|
||||
}
|
||||
|
||||
class Board{
|
||||
int width;
|
||||
int height;
|
||||
int bufferHeight;
|
||||
late List<List<Tetromino>> board;
|
||||
late int totalHeight;
|
||||
|
||||
Board(this.width, this.height, this.bufferHeight){
|
||||
totalHeight = height+bufferHeight;
|
||||
board = [for (var i = 0 ; i < totalHeight; i++) [for (var i = 0 ; i < width; i++) Tetromino.empty]];
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
String result = "";
|
||||
for (var row in board){
|
||||
for (var cell in row) result += cell.name[0];
|
||||
result += "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isOccupied(Coords coords)
|
||||
{
|
||||
if (coords.x < 0 || coords.x >= width ||
|
||||
coords.y < 0 || coords.y >= totalHeight ||
|
||||
board[coords.y][coords.x] != Tetromino.empty) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool positionIsValid(Tetromino type, Coords coords, int r){
|
||||
List<Coords> shape = shapes[type.index][r];
|
||||
for (Coords mino in shape){
|
||||
if (isOccupied(coords+mino)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void writeToBoard(Tetromino type, Coords coords, int rot) {
|
||||
if (!positionIsValid(type, coords, rot)) return;
|
||||
List<Coords> shape = shapes[type.index][rot];
|
||||
for (Coords mino in shape){
|
||||
var finalCoords = coords+mino;
|
||||
board[finalCoords.y][finalCoords.x] = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Simulation{
|
||||
|
||||
}
|
||||
|
||||
// That thing allows me to test my new staff i'm trying to implement
|
||||
void main() async {
|
||||
var replayJson = jsonDecode(File("/home/dan63047/Документы/replays/6550eecf2ffc5604e6224fc5.ttrm").readAsStringSync());
|
||||
ReplayData replay = ReplayData.fromJson(replayJson);
|
||||
List<Tetromino> queue = List.from(tetrominoes);
|
||||
TetrioRNG rng = TetrioRNG(replay.stats[0][0].seed);
|
||||
List<Tetromino> bag = rng.shuffleList(tetrominoes);
|
||||
List<Tetromino> queue = rng.shuffleList(tetrominoes);
|
||||
List<Event> events = readEventList(replay.rawJson);
|
||||
DataFullOptions? settings;
|
||||
HandlingHandler? handling;
|
||||
|
@ -90,100 +142,155 @@ void main() async {
|
|||
int currentFrame = 0;
|
||||
events.removeAt(0); // get rig of Event.start
|
||||
Event nextEvent = events.removeAt(0);
|
||||
List<List<Tetromino>> board = [for (var i = 0 ; i < 40; i++) [for (var i = 0 ; i < 10; i++) Tetromino.empty]];
|
||||
Tetromino current = bag.removeAt(0);
|
||||
Board board = Board(10, 20, 20);
|
||||
Tetromino? hold;
|
||||
int rot = 0;
|
||||
int x = 4;
|
||||
int y = 21;
|
||||
Coords coords = Coords(4, 21);
|
||||
double gravityBucket = 0.00000000000000;
|
||||
|
||||
x += spawnPositionFixes[current.index].x.toInt();
|
||||
y += spawnPositionFixes[current.index].y.toInt();
|
||||
developer.log("Seed is ${replay.stats[0][0].seed}, first bag is $queue");
|
||||
Tetromino current = queue.removeAt(0);
|
||||
//developer.log("Second bag is ${rng.shuffleList(tetrominoes)}");
|
||||
|
||||
int sonicDrop(){
|
||||
int height = coords.y;
|
||||
while (board.positionIsValid(current, Coords(coords.x, height), rot)){
|
||||
height -= 1;
|
||||
}
|
||||
height += 1;
|
||||
return height;
|
||||
}
|
||||
|
||||
Tetromino getNewOne(){
|
||||
if (queue.length <= 1) queue.addAll(rng.shuffleList(tetrominoes));
|
||||
developer.log("Next queue is $queue");
|
||||
return queue.removeAt(0);
|
||||
}
|
||||
|
||||
coords += spawnPositionFixes[current.index];
|
||||
for (currentFrame; currentFrame <= replay.roundLengths[0]; currentFrame++){
|
||||
gravityBucket += settings != null ? settings.g! : 0;
|
||||
gravityBucket += settings != null ? (handling!.sdfActive ? settings.g! * settings.handling!.sdf : settings.g!) : 0;
|
||||
|
||||
int movement = handling != null ? handling.process_movenent(1.0) : 0;
|
||||
if (board.positionIsValid(current, Coords(coords.x+movement, coords.y), rot)) coords.x += movement;
|
||||
|
||||
int gravityImpact = 0;
|
||||
if (gravityBucket >= 1.0){
|
||||
y -= gravityBucket.truncate();
|
||||
gravityImpact = gravityBucket.truncate();
|
||||
gravityBucket -= gravityBucket.truncate();
|
||||
}
|
||||
x += handling != null ? handling.process_movenent(1.0) : 0;
|
||||
print("$currentFrame: $x $y");
|
||||
if (board.positionIsValid(current, Coords(coords.x, coords.y-gravityImpact), rot)) coords.y -= gravityImpact;
|
||||
print("$currentFrame: $current at $coords\n$board");
|
||||
|
||||
if (currentFrame == nextEvent.frame){
|
||||
print("Processing $nextEvent");
|
||||
switch (nextEvent.type){
|
||||
case EventType.start:
|
||||
developer.log("go");
|
||||
break;
|
||||
case EventType.full:
|
||||
settings = (nextEvent as EventFull).data.options;
|
||||
handling = HandlingHandler(settings!.handling!.das.toDouble(), settings.handling!.arr.toDouble());
|
||||
break;
|
||||
case EventType.keydown:
|
||||
nextEvent as EventKeyPress;
|
||||
activeKeypresses[nextEvent.data.key] = nextEvent;
|
||||
switch (nextEvent.data.key){
|
||||
case KeyType.rotateCCW:
|
||||
rot = (rot-1)%4;
|
||||
break;
|
||||
case KeyType.rotateCW:
|
||||
rot = (rot+1)%4;
|
||||
break;
|
||||
case KeyType.rotate180:
|
||||
rot = (rot+2)%4;
|
||||
break;
|
||||
case KeyType.moveLeft:
|
||||
handling!.movement_key_pressed(true, false);
|
||||
case KeyType.moveRight:
|
||||
handling!.movement_key_pressed(false, true);
|
||||
case KeyType.softDrop:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.hardDrop:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.hold:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.chat:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.exit:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.retry:
|
||||
// TODO: Handle this case.
|
||||
default:
|
||||
developer.log(nextEvent.data.key.name);
|
||||
while (currentFrame == nextEvent.frame){
|
||||
//print("Processing $nextEvent");
|
||||
switch (nextEvent.type){
|
||||
case EventType.start:
|
||||
developer.log("go");
|
||||
break;
|
||||
case EventType.full:
|
||||
settings = (nextEvent as EventFull).data.options;
|
||||
handling = HandlingHandler(settings!.handling!.das.toDouble(), settings.handling!.arr.toDouble());
|
||||
break;
|
||||
case EventType.keydown:
|
||||
nextEvent as EventKeyPress;
|
||||
activeKeypresses[nextEvent.data.key] = nextEvent;
|
||||
switch (nextEvent.data.key){
|
||||
case KeyType.rotateCCW:
|
||||
rot = (rot+1)%4;
|
||||
break;
|
||||
case KeyType.rotateCW:
|
||||
rot = (rot-1)%4;
|
||||
break;
|
||||
case KeyType.rotate180:
|
||||
rot = (rot+2)%4;
|
||||
break;
|
||||
case KeyType.moveLeft:
|
||||
handling!.movement_key_pressed(true, false);
|
||||
break;
|
||||
case KeyType.moveRight:
|
||||
handling!.movement_key_pressed(false, true);
|
||||
break;
|
||||
case KeyType.softDrop:
|
||||
handling!.sdfActive = true;
|
||||
break;
|
||||
case KeyType.hardDrop:
|
||||
coords.y = sonicDrop();
|
||||
board.writeToBoard(current, coords, rot);
|
||||
current = getNewOne();
|
||||
coords = Coords(4, 21) + spawnPositionFixes[current.index];
|
||||
//handling!.movement_key_released(true, true);
|
||||
case KeyType.hold:
|
||||
switch (hold){
|
||||
case null:
|
||||
hold = current;
|
||||
current = getNewOne();
|
||||
break;
|
||||
case _:
|
||||
Tetromino temp;
|
||||
temp = hold;
|
||||
hold = current;
|
||||
current = temp;
|
||||
break;
|
||||
}
|
||||
coords = Coords(4, 21) + spawnPositionFixes[current.index];
|
||||
break;
|
||||
case KeyType.chat:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.exit:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.retry:
|
||||
// TODO: Handle this case.
|
||||
default:
|
||||
developer.log(nextEvent.data.key.name);
|
||||
}
|
||||
break;
|
||||
case EventType.keyup:
|
||||
nextEvent as EventKeyPress;
|
||||
switch (nextEvent.data.key){
|
||||
case KeyType.moveLeft:
|
||||
handling!.movement_key_released(true, false);
|
||||
break;
|
||||
case KeyType.moveRight:
|
||||
handling!.movement_key_released(false, true);
|
||||
break;
|
||||
case KeyType.softDrop:
|
||||
handling?.sdfActive = false;
|
||||
break;
|
||||
case KeyType.rotateCCW:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.rotateCW:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.rotate180:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.hardDrop:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.hold:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.chat:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.exit:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.retry:
|
||||
// TODO: Handle this case.
|
||||
}
|
||||
activeKeypresses.remove(nextEvent.data.key);
|
||||
break;
|
||||
case EventType.end:
|
||||
currentFrame = replay.roundLengths[0]+1;
|
||||
break;
|
||||
default:
|
||||
developer.log("Event wasn't processed: ${nextEvent}", level: 900);
|
||||
}
|
||||
try{
|
||||
nextEvent = events.removeAt(0);
|
||||
}
|
||||
break;
|
||||
case EventType.keyup:
|
||||
nextEvent as EventKeyPress;
|
||||
switch (nextEvent.data.key){
|
||||
case KeyType.moveLeft:
|
||||
handling!.movement_key_released(true, false);
|
||||
case KeyType.moveRight:
|
||||
handling!.movement_key_released(false, true);
|
||||
case KeyType.softDrop:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.rotateCCW:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.rotateCW:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.rotate180:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.hardDrop:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.hold:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.chat:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.exit:
|
||||
// TODO: Handle this case.
|
||||
case KeyType.retry:
|
||||
// TODO: Handle this case.
|
||||
catch (e){
|
||||
developer.log(e.toString());
|
||||
}
|
||||
activeKeypresses.remove(nextEvent.data.key);
|
||||
break;
|
||||
default:
|
||||
developer.log("Event wasn't processed: ${nextEvent}", level: 900);
|
||||
}
|
||||
nextEvent = events.removeAt(0);
|
||||
developer.log("Next is: $nextEvent");
|
||||
}
|
||||
//developer.log("Next is: $nextEvent");
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import 'tetrio.dart';
|
||||
|
||||
// I want to implement those fancy TWC stats
|
||||
|
@ -752,52 +750,72 @@ enum Tetromino{
|
|||
empty
|
||||
}
|
||||
|
||||
class Coords{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
Coords(this.x, this.y);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "($x; $y)";
|
||||
}
|
||||
|
||||
Coords operator+(Coords other){
|
||||
return Coords(x+other.x, y+other.y);
|
||||
}
|
||||
|
||||
Coords operator-(Coords other){
|
||||
return Coords(x-other.x, y-other.y);
|
||||
}
|
||||
}
|
||||
|
||||
List<Tetromino> tetrominoes = [Tetromino.Z, Tetromino.L, Tetromino.O, Tetromino.S, Tetromino.I, Tetromino.J, Tetromino.T];
|
||||
List<List<List<Vector2>>> shapes = [
|
||||
List<List<List<Coords>>> shapes = [
|
||||
[ // Z
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(2, 0), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(1, 2), Vector2(2, 2)],
|
||||
[Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(0, 2)]
|
||||
[Coords(0, 0), Coords(1, 0), Coords(1, 1), Coords(2, 1)],
|
||||
[Coords(2, 0), Coords(1, 1), Coords(2, 1), Coords(1, 2)],
|
||||
[Coords(0, 1), Coords(1, 1), Coords(1, 2), Coords(2, 2)],
|
||||
[Coords(1, 0), Coords(0, 1), Coords(1, 1), Coords(0, 2)]
|
||||
],
|
||||
[ // L
|
||||
[Vector2(2, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(1, 2), Vector2(2, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(0, 2)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(1, 2)]
|
||||
[Coords(2, 0), Coords(0, 1), Coords(1, 1), Coords(2, 1)],
|
||||
[Coords(1, 0), Coords(1, 1), Coords(1, 2), Coords(2, 2)],
|
||||
[Coords(0, 1), Coords(1, 1), Coords(2, 1), Coords(0, 2)],
|
||||
[Coords(0, 0), Coords(1, 0), Coords(1, 1), Coords(1, 2)]
|
||||
],
|
||||
[ // O
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(0, 0), Vector2(1, 0), Vector2(0, 1), Vector2(1, 1)]
|
||||
[Coords(0, 0), Coords(1, 0), Coords(0, 1), Coords(1, 1)],
|
||||
[Coords(0, 0), Coords(1, 0), Coords(0, 1), Coords(1, 1)],
|
||||
[Coords(0, 0), Coords(1, 0), Coords(0, 1), Coords(1, 1)],
|
||||
[Coords(0, 0), Coords(1, 0), Coords(0, 1), Coords(1, 1)]
|
||||
],
|
||||
[ // S
|
||||
[Vector2(1, 0), Vector2(2, 0), Vector2(0, 1), Vector2(1, 1)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(2, 1), Vector2(2, 2)],
|
||||
[Vector2(1, 1), Vector2(2, 1), Vector2(0, 2), Vector2(1, 2)],
|
||||
[Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 2)]
|
||||
[Coords(1, 0), Coords(2, 0), Coords(0, 1), Coords(1, 1)],
|
||||
[Coords(1, 0), Coords(1, 1), Coords(2, 1), Coords(2, 2)],
|
||||
[Coords(1, 1), Coords(2, 1), Coords(0, 2), Coords(1, 2)],
|
||||
[Coords(0, 0), Coords(0, 1), Coords(1, 1), Coords(1, 2)]
|
||||
],
|
||||
[ // I
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(3, 1)],
|
||||
[Vector2(2, 0), Vector2(2, 1), Vector2(2, 2), Vector2(2, 3)],
|
||||
[Vector2(0, 2), Vector2(1, 2), Vector2(2, 2), Vector2(3, 2)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(1, 2), Vector2(1, 3)]
|
||||
[Coords(0, 1), Coords(1, 1), Coords(2, 1), Coords(3, 1)],
|
||||
[Coords(2, 0), Coords(2, 1), Coords(2, 2), Coords(2, 3)],
|
||||
[Coords(0, 2), Coords(1, 2), Coords(2, 2), Coords(3, 2)],
|
||||
[Coords(1, 0), Coords(1, 1), Coords(1, 2), Coords(1, 3)]
|
||||
],
|
||||
[ // J
|
||||
[Vector2(0, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(1, 0), Vector2(2, 0), Vector2(1, 1), Vector2(1, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(2, 2)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(0, 2), Vector2(1, 2)]
|
||||
[Coords(0, 0), Coords(0, 1), Coords(1, 1), Coords(2, 1)],
|
||||
[Coords(1, 0), Coords(2, 0), Coords(1, 1), Coords(1, 2)],
|
||||
[Coords(0, 1), Coords(1, 1), Coords(2, 1), Coords(2, 2)],
|
||||
[Coords(1, 0), Coords(1, 1), Coords(0, 2), Coords(1, 2)]
|
||||
],
|
||||
[ // T
|
||||
[Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(2, 1)],
|
||||
[Vector2(1, 0), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
[Vector2(0, 1), Vector2(1, 1), Vector2(2, 1), Vector2(1, 2)],
|
||||
[Vector2(1, 0), Vector2(0, 1), Vector2(1, 1), Vector2(1, 2)]
|
||||
[Coords(1, 0), Coords(0, 1), Coords(1, 1), Coords(2, 1)],
|
||||
[Coords(1, 0), Coords(1, 1), Coords(2, 1), Coords(1, 2)],
|
||||
[Coords(0, 1), Coords(1, 1), Coords(2, 1), Coords(1, 2)],
|
||||
[Coords(1, 0), Coords(0, 1), Coords(1, 1), Coords(1, 2)]
|
||||
]
|
||||
];
|
||||
List<Vector2> spawnPositionFixes = [Vector2(1, 1), Vector2(1, 1), Vector2(0, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)];
|
||||
List<Coords> spawnPositionFixes = [Coords(1, 1), Coords(1, 1), Coords(0, 1), Coords(1, 1), Coords(1, 1), Coords(1, 1), Coords(1, 1)];
|
||||
|
||||
const Map<String, double> garbage = {
|
||||
"single": 0,
|
||||
|
|
Loading…
Reference in New Issue