diff --git a/lib/data_objects/freyhoe_test.dart b/lib/data_objects/freyhoe_test.dart index ee91554..29435e8 100644 --- a/lib/data_objects/freyhoe_test.dart +++ b/lib/data_objects/freyhoe_test.dart @@ -1,26 +1,26 @@ -// import 'dart:convert'; -// import 'dart:io'; +import 'dart:convert'; +import 'dart:io'; -// import 'package:path_provider/path_provider.dart'; +import 'package:path_provider/path_provider.dart'; -// import 'tetrio_multiplayer_replay.dart'; +import 'tetrio_multiplayer_replay.dart'; -// // That thing allows me to test my new staff i'm trying to implement -// void main() async { -// // List queue = List.from(tetrominoes); -// // TetrioRNG rng = TetrioRNG(0); -// // queue = rng.shuffleList(queue); -// // print(queue); -// // queue = List.from(tetrominoes); -// // queue = rng.shuffleList(queue); -// // print(queue); +// That thing allows me to test my new staff i'm trying to implement +void main() async { + // List queue = List.from(tetrominoes); + // TetrioRNG rng = TetrioRNG(0); + // queue = rng.shuffleList(queue); + // print(queue); + // queue = List.from(tetrominoes); + // queue = rng.shuffleList(queue); + // print(queue); -// //var downloadPath = await getDownloadsDirectory(); -// var replayJson = jsonDecode(File("/home/dan63047/Документы/replays/6550eecf2ffc5604e6224fc5.ttrm").readAsStringSync()); -// ReplayData replay = ReplayData.fromJson(replayJson); -// //List> board = [for (var i = 0 ; i < 40; i++) [for (var i = 0 ; i < 10; i++) Tetromino.empty]]; -// List events = readEventList(replay.rawJson); -// events.retainWhere((element) => element.type == EventType.ige); -// print((events[1] as EventIGE).data.data); -// exit(0); -// } \ No newline at end of file + //var downloadPath = await getDownloadsDirectory(); + var replayJson = jsonDecode(File("/home/dan63047/Документы/replays/6550eecf2ffc5604e6224fc5.ttrm").readAsStringSync()); + ReplayData replay = ReplayData.fromJson(replayJson); + //List> board = [for (var i = 0 ; i < 40; i++) [for (var i = 0 ; i < 10; i++) Tetromino.empty]]; + List events = readEventList(replay.rawJson); + //events.retainWhere((element) => element.runtimeType == EventIGE && (element as EventIGE).data.data['type'] == "interaction_confirm"); + print(events); + exit(0); +} \ No newline at end of file diff --git a/lib/data_objects/tetrio_multiplayer_replay.dart b/lib/data_objects/tetrio_multiplayer_replay.dart index 0ad4786..648727e 100644 --- a/lib/data_objects/tetrio_multiplayer_replay.dart +++ b/lib/data_objects/tetrio_multiplayer_replay.dart @@ -18,14 +18,14 @@ int biggestSpikeFromReplay(events){ spikeCounter = event['data']['data']['data']['amt']; biggestSpike = spikeCounter; }else{ - if (event['data']['data']['frame'] - previousIGEeventFrame < 60){ + if ((event['data']['data']['frame']??event['data']['frame']) - previousIGEeventFrame < 60){ spikeCounter = spikeCounter + event['data']['data']['data']['amt'] as int; }else{ spikeCounter = event['data']['data']['data']['amt']; } biggestSpike = max(biggestSpike, spikeCounter); } - previousIGEeventFrame = event['data']['data']['frame']; + previousIGEeventFrame = event['data']['data']['frame']??event['data']['frame']; } } return biggestSpike; @@ -218,8 +218,8 @@ class ReplayData{ List KPSmultipliedByWeights = [0, 0]; totalStats = [ReplayStats.createEmpty(), ReplayStats.createEmpty()]; for(var round in json['data']) { - int firstInEndContext = round['replays'][0]["events"].last['data']['export']['options']['gameid'].startsWith(endcontext[0].userId) ? 0 : 1; - int secondInEndContext = round['replays'][1]["events"].last['data']['export']['options']['gameid'].startsWith(endcontext[1].userId) ? 1 : 0; + int firstInEndContext = round['replays'][0]["events"].last['data']['export']['options']['username'].startsWith(endcontext[0].username) ? 0 : 1; + int secondInEndContext = round['replays'][1]["events"].last['data']['export']['options']['username'].startsWith(endcontext[1].username) ? 1 : 0; int roundLength = max(round['replays'][0]['frames'], round['replays'][1]['frames']); roundLengths.add(roundLength); totalLength = totalLength + max(round['replays'][0]['frames'], round['replays'][1]['frames']); @@ -230,7 +230,7 @@ class ReplayData{ VSmultipliedByWeights[0] += endcontext[0].extraTracking[roundID]*roundLength; VSmultipliedByWeights[1] += endcontext[1].extraTracking[roundID]*roundLength; int winner = round['board'].indexWhere((element) => element['success'] == true); - roundWinners.add([round['board'][winner]['id'], round['board'][winner]['username']]); + roundWinners.add([round['board'][winner]['id']??round['board'][winner]['user']['_id'], round['board'][winner]['username']??round['board'][winner]['user']['username']]); ReplayStats playerOne = ReplayStats.fromJson(round['replays'][firstInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][secondInEndContext]['events']), round['replays'][firstInEndContext]['frames']); // (events contain recived attacks) ReplayStats playerTwo = ReplayStats.fromJson(round['replays'][secondInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][firstInEndContext]['events']), round['replays'][secondInEndContext]['frames']); SPPmultipliedByWeights[0] += playerOne.spp*roundLength; @@ -271,516 +271,554 @@ class ReplayData{ // can't belive i have to implement that difficult shit -// List readEventList(Map json){ -// List events = []; -// int id = 0; -// for (var event in json['data'][0]['replays'][0]['events']){ -// int frame = event["frame"]; -// EventType type = EventType.values.byName(event['type']); -// switch (type) { -// case EventType.start: -// events.add(Event(id, frame, type)); -// break; -// case EventType.full: -// events.add(EventFull(id, frame, type, DataFull.fromJson(event["data"]))); -// break; -// case EventType.targets: -// events.add(EventTargets(id, frame, type, Targets.fromJson(event["data"]))); -// break; -// case EventType.keydown: -// events.add(EventKeyPress(id, frame, type, -// Keypress( -// KeyType.values.byName(event['data']['key']), -// event['data']['subframe'], -// false) -// )); -// break; -// case EventType.keyup: -// events.add(EventKeyPress(id, frame, type, -// Keypress( -// KeyType.values.byName(event['data']['key']), -// event['data']['subframe'], -// true) -// )); -// break; -// case EventType.end: -// events.add(EventEnd(id, frame, type, EndData(event['data']['reason'], DataFull.fromJson(event['data']['export'])))); -// break; -// case EventType.ige: -// events.add(EventIGE(id, frame, type, IGE( -// event['data']['id'], -// event['data']['frame'], -// event['data']['type'], -// event['data']['data'] -// )) -// ); -// break; -// case EventType.exit: -// events.add(Event(id, frame, type)); -// break; -// } -// id++; -// } -// return events; -// } +List readEventList(Map json){ + List events = []; + int id = 0; + for (var event in json['data'][0]['replays'][0]['events']){ + int frame = event["frame"]; + EventType type = EventType.values.byName(event['type']); + switch (type) { + case EventType.start: + events.add(Event(id, frame, type)); + break; + case EventType.full: + events.add(EventFull(id, frame, type, DataFull.fromJson(event["data"]))); + break; + case EventType.targets: + events.add(EventTargets(id, frame, type, Targets.fromJson(event["data"]))); + break; + case EventType.keydown: + events.add(EventKeyPress(id, frame, type, + Keypress( + KeyType.values.byName(event['data']['key']), + event['data']['subframe'], + false) + )); + break; + case EventType.keyup: + events.add(EventKeyPress(id, frame, type, + Keypress( + KeyType.values.byName(event['data']['key']), + event['data']['subframe'], + true) + )); + break; + case EventType.end: + events.add(EventEnd(id, frame, type, EndData(event['data']['reason'], DataFull.fromJson(event['data']['export'])))); + break; + case EventType.ige: + events.add(EventIGE(id, frame, type, IGE( + event['data']['id'], + event['data']['frame'], + event['data']['type'], + event['data']['data'] + )) + ); + break; + case EventType.exit: + events.add(Event(id, frame, type)); + break; + } + id++; + } + return events; +} -// enum EventType -// { -// start, -// end, -// full, -// keydown, -// keyup, -// targets, -// ige, -// exit -// } +enum EventType +{ + start, + end, + full, + keydown, + keyup, + targets, + ige, + exit +} -// enum KeyType -// { -// moveLeft, -// moveRight, -// softDrop, -// rotateCCW, -// rotateCW, -// rotate180, -// hardDrop, -// hold, -// chat, -// exit, -// retry -// } +enum KeyType +{ + moveLeft, + moveRight, + softDrop, + rotateCCW, + rotateCW, + rotate180, + hardDrop, + hold, + chat, + exit, + retry +} -// class Event{ -// int id; -// int frame; -// EventType type; -// //dynamic data; +class Event{ + int id; + int frame; + EventType type; + //dynamic data; -// Event(this.id, this.frame, this.type); + Event(this.id, this.frame, this.type); -// @override -// String toString(){ -// return "E#$id f#$frame: $type"; -// } -// } + @override + String toString(){ + return "E#$id f#$frame: $type"; + } +} -// class Keypress{ -// KeyType key; -// late double subframe; -// bool released; +class Keypress{ + KeyType key; + late double subframe; + bool released; -// Keypress(this.key, num sframe, this.released){ -// subframe = sframe.toDouble(); -// } -// } + Keypress(this.key, num sframe, this.released){ + subframe = sframe.toDouble(); + } +} -// class EventKeyPress extends Event{ -// Keypress data; +class EventKeyPress extends Event{ + Keypress data; -// EventKeyPress(super.id, super.frame, super.type, this.data); -// } + EventKeyPress(super.id, super.frame, super.type, this.data); +} -// class Targets{ -// String? id; -// int? frame; -// String? type; -// List? data; +class Targets{ + String? id; + int? frame; + String? type; + List? data; -// Targets(this.id, this.frame, this.type, this.data); + Targets(this.id, this.frame, this.type, this.data); -// Targets.fromJson(Map json){ -// id = json["id"]; -// frame = json["frame"]; -// type = json["type"]; -// data = json["data"]; -// } -// } + Targets.fromJson(Map json){ + id = json["id"]; + frame = json["frame"]; + type = json["type"]; + data = json["data"]; + } +} -// class EventTargets extends Event{ -// Targets data; +class EventTargets extends Event{ + Targets data; -// EventTargets(super.id, super.frame, super.type, this.data); -// } + EventTargets(super.id, super.frame, super.type, this.data); +} -// class IGEdata{ - -// } +class IGEdata{ + late String type; + late String? gameid; + late int? frame; -// enum GarbageStatus -// { -// sleeping, -// caution, -// spawn, -// danger -// } + IGEdata.fromJson(Map d){ + type = d['type']; + gameid = d['gameid']; + frame = d['frame']; + } +} -// class GarbageData{ -// int? id; -// late int iid; -// late int ackiid; -// String? username; -// late String type; -// bool? active; -// GarbageStatus? status; -// int? delay; -// bool? queued; -// late int amt; -// late int x; -// late int y; -// int? size; -// late int column; -// int? cid; -// bool? firstcycle; -// int? gid; +enum GarbageStatus +{ + sleeping, + caution, + spawn, + danger +} -// GarbageData.fromJson(Map data){ -// id = data['id']; -// iid = data['iid']; -// ackiid = data['ackiid']; -// username = data['username']; -// type = data['type']; -// active = data['active']; -// status = data['status'] != null ? GarbageStatus.values[data['status']] : null; -// delay = data['delay']; -// queued = data['queued']; -// amt = data['amt']; -// x = data['x']; -// y = data['y']; -// size = data['size']; -// column = data['column']; -// cid = data['cid']; -// firstcycle = data['firstcycle']; -// gid = data['gid']; -// } -// } +class GarbageData{ + int? id; + int? iid; + int? ackiid; + String? username; + late String type; + bool? active; + GarbageStatus? status; + int? delay; + bool? queued; + int? amt; + int? x; + int? y; + int? size; + int? column; + int? cid; + bool? firstcycle; + int? gid; + bool? value; -// class IGEdataTarget extends IGEdata{ -// late String type; -// late List targets; -// late int frame; + GarbageData.fromJson(Map data){ + id = data['id']; + iid = data['iid']; + ackiid = data['ackiid']; + username = data['username']; + type = data['type']; + active = data['active']; + status = data['status'] != null ? GarbageStatus.values[data['status']] : null; + delay = data['delay']; + queued = data['queued']; + amt = data['amt']; + x = data['x']; + y = data['y']; + size = data['size']; + column = data['column']; + cid = data['cid']; + firstcycle = data['firstcycle']; + gid = data['gid']; + value = data['value']; + } +} + +class IGEdataTarget extends IGEdata{ + late List targets; -// late String gameid; -// GarbageData? data; -// //compatibility for v15 targets event -// String? sender_id; + GarbageData? data; + //compatibility for v15 targets event + String? sender_id; -// IGEdataTarget.fromJson(Map d){ -// type = d['type']; -// targets = d['targets']; -// frame = d['targets']; -// gameid = d['gameid']; -// data = GarbageData.fromJson(d['data']); -// } -// } + IGEdataTarget.fromJson(Map d) : super.fromJson(d){ + targets = d['targets']; + data = d['data'] != null ? GarbageData.fromJson(d['data']) : null; + } +} -// class IGE{ -// int id; -// int frame; -// String type; -// Map data; +class IGEdataAllowTargeting extends IGEdata{ + late bool value; -// IGE(this.id, this.frame, this.type, this.data); -// } + IGEdataAllowTargeting.fromJson(Map d) : super.fromJson(d){ + value = d['value']; + frame = d['frame']; + } +} -// class EventIGE extends Event{ -// IGE data; +class IGEdataInteraction extends IGEdata{ + late GarbageData data; + String? sender; + String? senderID; + int? sentFrame; + bool confirm = false; + -// EventIGE(super.id, super.frame, super.type, this.data); -// } + IGEdataInteraction.fromJson(Map d) : super.fromJson(d){ + //data = Targeted(d['data']['targeted'], d['data']['value']); + data = GarbageData.fromJson(d['data']); + sender = d['sender']; + senderID = d['sender_id']; + confirm = type == "interaction_confirm"; + } +} -// class EndData { -// String reason; -// DataFull export; +class IGE{ + int id; + int frame; + String type; + late IGEdata data; -// EndData(this.reason, this.export); -// } + IGE(this.id, this.frame, this.type, Map d){ + data = switch (d["type"] as String) { + "interaction" => IGEdataInteraction.fromJson(d), + "interaction_confirm" => IGEdataInteraction.fromJson(d), + "target" => IGEdataTarget.fromJson(d), + "allow_targeting" => IGEdataAllowTargeting.fromJson(d), + _ => IGEdata.fromJson(d), + }; + } +} -// class EventEnd extends Event{ -// EndData data; +class EventIGE extends Event{ + IGE data; -// EventEnd(super.id, super.frame, super.type, this.data); -// } + EventIGE(super.id, super.frame, super.type, this.data); +} -// class Hold -// { -// String? piece; -// bool locked; +class EndData { + String reason; + DataFull export; -// Hold(this.piece, this.locked); -// } + EndData(this.reason, this.export); +} -// class DataFullOptions{ -// int? version; -// bool? seedRandom; -// int? seed; -// double? g; -// int? stock; -// int? gMargin; -// double? gIncrease; -// double? garbageMultiplier; -// int? garbageMargin; -// double? garbageIncrease; -// int? garbageCap; -// double? garbageCapIncrease; -// int? garbageCapMax; -// int? garbageHoleSize; -// String? garbageBlocking; // TODO: enum -// bool? hasGarbage; -// int? locktime; -// int? garbageSpeed; -// int? forfeitTime; -// int? are; -// int? areLineclear; -// bool? infiniteMovement; -// int? lockresets; -// bool? allow180; -// bool? btbChaining; -// bool? allclears; -// bool? clutch; -// bool? noLockout; -// String? passthrough; -// int? boardwidth; -// int? boardheight; -// Handling? handling; -// int? boardbuffer; +class EventEnd extends Event{ + EndData data; -// DataFullOptions.fromJson(Map json){ -// version = json["version"]; -// seedRandom = json["seed_random"]; -// seed = json["seed"]; -// g = json["g"]; -// stock = json["stock"]; -// gMargin = json["gmargin"]; -// gIncrease = json["gincrease"]; -// garbageMultiplier = json["garbagemultiplier"].toDouble(); -// garbageCapIncrease = json["garbagecapincrease"].toDouble(); -// garbageCapMax = json["garbagecapmax"]; -// garbageHoleSize = json["garbageholesize"]; -// garbageBlocking = json["garbageblocking"]; -// hasGarbage = json["hasgarbage"]; -// locktime = json["locktime"]; -// garbageSpeed = json["garbagespeed"]; -// forfeitTime = json["forfeit_time"]; -// are = json["are"]; -// areLineclear = json["lineclear_are"]; -// infiniteMovement = json["infinitemovement"]; -// lockresets = json["lockresets"]; -// allow180 = json["allow180"]; -// btbChaining = json["b2bchaining"]; -// allclears = json["allclears"]; -// clutch = json["clutch"]; -// noLockout = json["nolockout"]; -// passthrough = json["passthrough"]; -// boardwidth = json["boardwidth"]; -// boardheight = json["boardheight"]; -// handling = Handling.fromJson(json["handling"]); -// boardbuffer = json["boardbuffer"]; -// } -// } + EventEnd(super.id, super.frame, super.type, this.data); +} -// class DataFullStats -// { -// int? seed; -// int? lines; -// int? levelLines; -// int? levelLinesNeeded; -// int? inputs; -// int? holds; -// int? score; -// int? zenLevel; -// int? zenProgress; -// int? level; -// int? combo; -// int? currentComboPower; -// int? topCombo; -// int? btb; -// int? topbtb; -// int? tspins; -// int? piecesPlaced; -// Clears? clears; -// Garbage? garbage; -// int? kills; -// Finesse? finesse; +class Hold +{ + String? piece; + bool locked; -// DataFullStats.fromJson(Map json){ -// seed = json["seed"]; -// lines = json["lines"]; -// levelLines = json["level_lines"]; -// levelLinesNeeded = json["level_lines_needed"]; -// inputs = json["inputs"]; -// holds = json["holds"]; -// score = json["score"]; -// zenLevel = json["zenlevel"]; -// zenProgress = json["zenprogress"]; -// level = json["level"]; -// combo = json["combo"]; -// currentComboPower = json["currentcombopower"]; -// topCombo = json["topcombo"]; -// btb = json["btb"]; -// topbtb = json["topbtb"]; -// tspins = json["tspins"]; -// piecesPlaced = json["piecesplaced"]; -// clears = Clears.fromJson(json["clears"]); -// garbage = Garbage.fromJson(json["garbage"]); -// kills = json["kills"]; -// finesse = Finesse.fromJson(json["finesse"]); -// } -// } + Hold(this.piece, this.locked); +} -// class DataFullGame -// { -// List? board; -// List? bag; -// double? g; -// bool? playing; -// Hold? hold; -// String? piece; -// Handling? handling; +class DataFullOptions{ + int? version; + bool? seedRandom; + int? seed; + double? g; + int? stock; + int? gMargin; + double? gIncrease; + double? garbageMultiplier; + int? garbageMargin; + double? garbageIncrease; + int? garbageCap; + double? garbageCapIncrease; + int? garbageCapMax; + int? garbageHoleSize; + String? garbageBlocking; // TODO: enum + bool? hasGarbage; + int? locktime; + int? garbageSpeed; + int? forfeitTime; + int? are; + int? areLineclear; + bool? infiniteMovement; + int? lockresets; + bool? allow180; + bool? btbChaining; + bool? allclears; + bool? clutch; + bool? noLockout; + String? passthrough; + int? boardwidth; + int? boardheight; + Handling? handling; + int? boardbuffer; -// DataFullGame.fromJson(Map json){ -// board = json["board"]; -// bag = json["bag"]; -// hold = Hold(json["hold"]["piece"], json["hold"]["locked"]); -// g = json["g"]; -// handling = Handling.fromJson(json["handling"]); -// } -// } + DataFullOptions.fromJson(Map json){ + version = json["version"]; + seedRandom = json["seed_random"]; + seed = json["seed"]; + g = json["g"]; + stock = json["stock"]; + gMargin = json["gmargin"]; + gIncrease = json["gincrease"]; + garbageMultiplier = json["garbagemultiplier"].toDouble(); + garbageCapIncrease = json["garbagecapincrease"].toDouble(); + garbageCapMax = json["garbagecapmax"]; + garbageHoleSize = json["garbageholesize"]; + garbageBlocking = json["garbageblocking"]; + hasGarbage = json["hasgarbage"]; + locktime = json["locktime"]; + garbageSpeed = json["garbagespeed"]; + forfeitTime = json["forfeit_time"]; + are = json["are"]; + areLineclear = json["lineclear_are"]; + infiniteMovement = json["infinitemovement"]; + lockresets = json["lockresets"]; + allow180 = json["allow180"]; + btbChaining = json["b2bchaining"]; + allclears = json["allclears"]; + clutch = json["clutch"]; + noLockout = json["nolockout"]; + passthrough = json["passthrough"]; + boardwidth = json["boardwidth"]; + boardheight = json["boardheight"]; + handling = Handling.fromJson(json["handling"]); + boardbuffer = json["boardbuffer"]; + } +} -// class DataFull{ -// bool? successful; -// String? gameOverReason; -// int? fire; -// DataFullOptions? options; -// DataFullStats? stats; -// DataFullGame? game; +class DataFullStats + { + int? seed; + int? lines; + int? levelLines; + int? levelLinesNeeded; + int? inputs; + int? holds; + int? score; + int? zenLevel; + int? zenProgress; + int? level; + int? combo; + int? currentComboPower; + int? topCombo; + int? btb; + int? topbtb; + int? tspins; + int? piecesPlaced; + Clears? clears; + Garbage? garbage; + int? kills; + Finesse? finesse; -// DataFull.fromJson(Map json){ -// successful = json["successful"]; -// gameOverReason = json["gameoverreason"]; -// fire = json["fire"]; -// options = DataFullOptions.fromJson(json["options"]); -// stats = DataFullStats.fromJson(json["stats"]); -// game = DataFullGame.fromJson(json["game"]); -// } -// } + DataFullStats.fromJson(Map json){ + seed = json["seed"]; + lines = json["lines"]; + levelLines = json["level_lines"]; + levelLinesNeeded = json["level_lines_needed"]; + inputs = json["inputs"]; + holds = json["holds"]; + score = json["score"]; + zenLevel = json["zenlevel"]; + zenProgress = json["zenprogress"]; + level = json["level"]; + combo = json["combo"]; + currentComboPower = json["currentcombopower"]; + topCombo = json["topcombo"]; + btb = json["btb"]; + topbtb = json["topbtb"]; + tspins = json["tspins"]; + piecesPlaced = json["piecesplaced"]; + clears = Clears.fromJson(json["clears"]); + garbage = Garbage.fromJson(json["garbage"]); + kills = json["kills"]; + finesse = Finesse.fromJson(json["finesse"]); + } + } -// class EventFull extends Event{ -// DataFull data; +class DataFullGame + { + List? board; + List? bag; + double? g; + bool? playing; + Hold? hold; + String? piece; + Handling? handling; -// EventFull(super.id, super.frame, super.type, this.data); -// } + DataFullGame.fromJson(Map json){ + board = json["board"]; + bag = json["bag"]; + hold = Hold(json["hold"]["piece"], json["hold"]["locked"]); + g = json["g"]; + handling = Handling.fromJson(json["handling"]); + } + } -// class TetrioRNG{ -// late double _t; +class DataFull{ + bool? successful; + String? gameOverReason; + int? fire; + DataFullOptions? options; + DataFullStats? stats; + DataFullGame? game; -// TetrioRNG(int seed){ -// _t = seed % 2147483647; -// if (_t <= 0) _t += 2147483646; -// } + DataFull.fromJson(Map json){ + successful = json["successful"]; + gameOverReason = json["gameoverreason"]; + fire = json["fire"]; + options = DataFullOptions.fromJson(json["options"]); + stats = DataFullStats.fromJson(json["stats"]); + game = DataFullGame.fromJson(json["game"]); + } +} -// int next(){ -// _t = 16807 * _t % 2147483647; -// return _t.toInt(); -// } +class EventFull extends Event{ + DataFull data; -// double nextFloat(){ -// return (next() - 1) / 2147483646; -// } + EventFull(super.id, super.frame, super.type, this.data); +} -// List shuffleList(List array){ -// int length = array.length; -// if (length == 0) return []; +class TetrioRNG{ + late double _t; -// for (; --length > 0;){ -// int swapIndex = ((nextFloat()) * (length + 1)).toInt(); -// Tetromino tmp = array[length]; -// array[length] = array[swapIndex]; -// array[swapIndex] = tmp; -// } -// return array; -// } -// } + TetrioRNG(int seed){ + _t = seed % 2147483647; + if (_t <= 0) _t += 2147483646; + } -// enum Tetromino{ -// Z, -// L, -// O, -// S, -// I, -// J, -// T, -// garbage, -// empty -// } + int next(){ + _t = 16807 * _t % 2147483647; + return _t.toInt(); + } -// List tetrominoes = [Tetromino.Z, Tetromino.L, Tetromino.O, Tetromino.S, Tetromino.I, Tetromino.J, Tetromino.T]; -// List>> 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)] -// ], -// [ // 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)] -// ], -// [ // 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)] -// ], -// [ // 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)] -// ], -// [ // 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)] -// ], -// [ // 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)] -// ], -// [ // 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)] -// ] -// ]; -// List spawnPositionFixes = [Vector2(1, 1), Vector2(1, 1), Vector2(0, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)]; + double nextFloat(){ + return (next() - 1) / 2147483646; + } -// const Map garbage = { -// "single": 0, -// "double": 1, -// "triple": 2, -// "quad": 4, -// "penta": 5, -// "t-spin": 0, -// "t-spin single": 2, -// "t-spin double": 4, -// "t-spin triple": 6, -// "t-spin quad": 10, -// "t-spin penta": 12, -// "t-spin mini": 0, -// "t-spin mini single": 0, -// "t-spin mini double": 1, -// "allclear": 10 -// }; -// int btbBonus = 1; -// double btbLog = 0.8; -// double comboBonus = 0.25; -// int comboMinifier = 1; -// double comboMinifierLog = 1.25; -// List comboTable = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5]; + List shuffleList(List array){ + int length = array.length; + if (length == 0) return []; + + for (; --length > 0;){ + int swapIndex = ((nextFloat()) * (length + 1)).toInt(); + Tetromino tmp = array[length]; + array[length] = array[swapIndex]; + array[swapIndex] = tmp; + } + return array; + } +} + +enum Tetromino{ + Z, + L, + O, + S, + I, + J, + T, + garbage, + empty +} + +List tetrominoes = [Tetromino.Z, Tetromino.L, Tetromino.O, Tetromino.S, Tetromino.I, Tetromino.J, Tetromino.T]; +List>> 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)] + ], + [ // 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)] + ], + [ // 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)] + ], + [ // 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)] + ], + [ // 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)] + ], + [ // 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)] + ], + [ // 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)] + ] +]; +List spawnPositionFixes = [Vector2(1, 1), Vector2(1, 1), Vector2(0, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1), Vector2(1, 1)]; + +const Map garbage = { + "single": 0, + "double": 1, + "triple": 2, + "quad": 4, + "penta": 5, + "t-spin": 0, + "t-spin single": 2, + "t-spin double": 4, + "t-spin triple": 6, + "t-spin quad": 10, + "t-spin penta": 12, + "t-spin mini": 0, + "t-spin mini single": 0, + "t-spin mini double": 1, + "allclear": 10 +}; +int btbBonus = 1; +double btbLog = 0.8; +double comboBonus = 0.25; +int comboMinifier = 1; +double comboMinifierLog = 1.25; +List comboTable = [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5];