import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } LoopCalculationResults runLoopGame( LoopCalculationInput input ) { List chartLogs = []; int sessionDifference = 0; int userBalance = input.userBalance; int casinoBalance = input.casinoBalance; int actualBid = input.actualBid; int bidIncrease = input.bidIncrease; int playTimes = input.playTimes; for (int i = 0; i < playTimes; i++) { final bool didWin = Random.secure().nextBool(); if (didWin) { userBalance = userBalance + actualBid; casinoBalance = casinoBalance - actualBid; sessionDifference += actualBid; chartLogs.add(ChartItem(i, userBalance, actualBid)); } else { userBalance = userBalance - actualBid; casinoBalance = casinoBalance + actualBid; sessionDifference -= actualBid; chartLogs.add(ChartItem(i, userBalance, -actualBid)); } actualBid += bidIncrease; } return LoopCalculationResults( userBalance, casinoBalance, actualBid, sessionDifference, chartLogs, ); } class ChartItem { ChartItem(this.index, this.value, this.delta); final int index; final int value; final int delta; } class LoopCalculationInput { final int userBalance; final int casinoBalance; final int actualBid; final int bidIncrease; final int playTimes; LoopCalculationInput(this.userBalance, this.casinoBalance, this.actualBid, this.bidIncrease, this.playTimes); } class LoopCalculationResults { final int userBalance; final int casinoBalance; final int actualBid; final int sessionDifference; final List chartLogs; LoopCalculationResults(this.userBalance, this.casinoBalance, this.actualBid, this.sessionDifference, this.chartLogs); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Dice'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { bool isCalculating = false; int casinoBalance = 100000000000; int userBalance = 10000; int bid = 10; int bidIncrease = 0; int playTimes = 1; List logs = []; List chartLogs = []; final ScrollController _scrollController = ScrollController(); final TextEditingController _bidEditingController = TextEditingController(text: '10'); final TextEditingController _userBalanceEditingController = TextEditingController(text: '10000'); final TextEditingController _casinoBalanceEditingController = TextEditingController(text: '100000000000'); void runGame() async { int actualBid = bid; setState(() { isCalculating = true; }); chartLogs.clear(); // final LoopCalculationResults results = runLoopGame(userBalance, casinoBalance, actualBid, bidIncrease, playTimes); final input = LoopCalculationInput(userBalance, casinoBalance, actualBid, bidIncrease, playTimes); final LoopCalculationResults results = await compute(runLoopGame, input); actualBid = results.actualBid; casinoBalance = results.casinoBalance; userBalance = results.userBalance; int sessionDifference = results.sessionDifference; chartLogs = results.chartLogs; _userBalanceEditingController.text = userBalance.toString(); _casinoBalanceEditingController.text = casinoBalance.toString(); if (sessionDifference >= 0) { logs.add('Игрок выиграл: +$sessionDifference, игр: $playTimes'); } else { logs.add('Игрок проиграл: $sessionDifference, игр: $playTimes'); } setState(() { bid = actualBid; _bidEditingController.text = actualBid.toString(); isCalculating = false; }); Future.delayed(Duration(milliseconds: 50)).then((value) { WidgetsBinding.instance!.addPostFrameCallback((timeStamp) { _scrollController.jumpTo(_scrollController.position.maxScrollExtent); }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: SafeArea( child: GestureDetector( onTap: () { FocusScope.of(context).unfocus(); }, child: Column( children: [ Expanded( child: Row( children: [ Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 20), Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( offset: const Offset(0, 16), color: const Color(0xFF0A0A5C).withOpacity(0.08), blurRadius: 40, spreadRadius: -12, ) ], ), child: Container( height: 50, width: 250, child: TextFormField( controller: _casinoBalanceEditingController, // initialValue: casinoBalance.toString(), style: TextStyle( fontSize: 22, fontWeight: FontWeight.w400, height: 1.41, color: Color(0xFF14151F), decoration: TextDecoration.none, ), autovalidateMode: AutovalidateMode.disabled, onEditingComplete: () {}, decoration: const InputDecoration( labelText: 'Баланс казино', labelStyle: TextStyle( fontSize: 20, fontWeight: FontWeight.w400, height: 1.41, color: Color(0xFF9698A9), decoration: TextDecoration.none, ), isDense: true, alignLabelWithHint: true, border: UnderlineInputBorder( borderSide: BorderSide( color: Color(0xFFECF0F3), width: 1), borderRadius: BorderRadius.zero), ), textCapitalization: TextCapitalization.words, onChanged: (value) { if (int.tryParse(value) != null) { casinoBalance = int.tryParse(value)!; } }, validator: (value) { return null; }, ), ), ), const SizedBox(height: 10), Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( offset: const Offset(0, 16), color: const Color(0xFF0A0A5C).withOpacity(0.08), blurRadius: 40, spreadRadius: -12, ) ], ), child: Container( height: 50, width: 250, child: TextFormField( controller: _userBalanceEditingController, // initialValue: userBalance.toString(), style: TextStyle( fontSize: 22, fontWeight: FontWeight.w400, height: 1.41, color: Color(0xFF14151F), decoration: TextDecoration.none, ), autovalidateMode: AutovalidateMode.disabled, onEditingComplete: () {}, decoration: const InputDecoration( labelText: 'Баланс игрока', labelStyle: TextStyle( fontSize: 20, fontWeight: FontWeight.w400, height: 1.41, color: Color(0xFF9698A9), decoration: TextDecoration.none, ), isDense: true, alignLabelWithHint: true, border: UnderlineInputBorder( borderSide: BorderSide( color: Color(0xFFECF0F3), width: 1), borderRadius: BorderRadius.zero), ), textCapitalization: TextCapitalization.words, onChanged: (value) { if (int.tryParse(value) != null) { userBalance = int.tryParse(value)!; } }, validator: (value) { return null; }, ), ), ), ], ), ), Container( height: double.maxFinite, width: 1, color: Colors.grey, ), Expanded( child: Container( margin: const EdgeInsets.only(top: 10, left: 10), child: Column( children: [ Expanded( child: ListView.builder( // reverse: true, controller: _scrollController, itemCount: logs.length, itemBuilder: (context, index) { return Text(logs[index]); }, ), ), ], ), ), ) ], ), ), Expanded( child: Container( margin: const EdgeInsets.all(20), padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( offset: const Offset(0, 16), color: const Color(0xFF0A0A5C).withOpacity(0.08), blurRadius: 40, spreadRadius: -12, ) ], ), child: Row( children: [ Column( children: [ SizedBox(height: 20), Container( height: 50, width: 250, child: TextFormField( controller: _bidEditingController, style: TextStyle( fontSize: 22, fontWeight: FontWeight.w400, height: 1.41, color: Color(0xFF14151F), decoration: TextDecoration.none, ), autovalidateMode: AutovalidateMode.disabled, onEditingComplete: () {}, decoration: const InputDecoration( labelText: 'Ставка', labelStyle: TextStyle( fontSize: 20, fontWeight: FontWeight.w400, height: 1.41, color: Color(0xFF9698A9), decoration: TextDecoration.none, ), isDense: true, alignLabelWithHint: true, border: UnderlineInputBorder( borderSide: BorderSide( color: Color(0xFFECF0F3), width: 1), borderRadius: BorderRadius.zero), ), textCapitalization: TextCapitalization.words, onChanged: (value) { if (int.tryParse(value) != null) { bid = int.tryParse(value)!; } }, validator: (value) { return null; }, ), ), ], ), ], ), ), ), ], ), ), ), floatingActionButton: FloatingActionButton( backgroundColor: isCalculating ? Colors.grey : null, onPressed: () { if (!isCalculating) { runGame(); } }, child: isCalculating ? CupertinoActivityIndicator() : Text('Play'), ), ); } }