From 00293b89dfa2c99f6944ba7805d28efa486469bd Mon Sep 17 00:00:00 2001 From: Gleb Shalimov Date: Sat, 28 Mar 2026 11:03:13 +0300 Subject: [PATCH 1/5] added new levels (111-120) --- lib/data/levels/level_111.json | 11 +++++++++++ lib/data/levels/level_112.json | 11 +++++++++++ lib/data/levels/level_113.json | 11 +++++++++++ lib/data/levels/level_114.json | 11 +++++++++++ lib/data/levels/level_115.json | 11 +++++++++++ lib/data/levels/level_116.json | 11 +++++++++++ lib/data/levels/level_117.json | 11 +++++++++++ lib/data/levels/level_118.json | 11 +++++++++++ lib/data/levels/level_119.json | 11 +++++++++++ lib/data/levels/level_120.json | 11 +++++++++++ 10 files changed, 110 insertions(+) create mode 100644 lib/data/levels/level_111.json create mode 100644 lib/data/levels/level_112.json create mode 100644 lib/data/levels/level_113.json create mode 100644 lib/data/levels/level_114.json create mode 100644 lib/data/levels/level_115.json create mode 100644 lib/data/levels/level_116.json create mode 100644 lib/data/levels/level_117.json create mode 100644 lib/data/levels/level_118.json create mode 100644 lib/data/levels/level_119.json create mode 100644 lib/data/levels/level_120.json diff --git a/lib/data/levels/level_111.json b/lib/data/levels/level_111.json new file mode 100644 index 0000000..d6b128f --- /dev/null +++ b/lib/data/levels/level_111.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "1", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["0", "1", "1", "1", "1", "1", "0"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "1", "1", "1", "1", "1"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_112.json b/lib/data/levels/level_112.json new file mode 100644 index 0000000..51c604a --- /dev/null +++ b/lib/data/levels/level_112.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "1", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["1", "1", "0", "1", "0", "1", "1"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "0", "1", "0", "1", "1"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "0", "1", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_113.json b/lib/data/levels/level_113.json new file mode 100644 index 0000000..08d4a03 --- /dev/null +++ b/lib/data/levels/level_113.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["1", "1", "0", "1", "0", "1", "1"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "0", "1", "0", "1", "1"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "0", "0", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_114.json b/lib/data/levels/level_114.json new file mode 100644 index 0000000..2579ba7 --- /dev/null +++ b/lib/data/levels/level_114.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "0", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "1", "1", "1", "1", "1"], + ["0", "1", "1", "0", "1", "1", "0"], + ["x", "x", "0", "1", "0", "x", "x"], + ["x", "x", "0", "0", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_115.json b/lib/data/levels/level_115.json new file mode 100644 index 0000000..3403d83 --- /dev/null +++ b/lib/data/levels/level_115.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "0", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["0", "1", "1", "1", "1", "1", "1"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "1", "1", "1", "1", "0"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "0", "0", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_116.json b/lib/data/levels/level_116.json new file mode 100644 index 0000000..1f754bc --- /dev/null +++ b/lib/data/levels/level_116.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "1", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["0", "1", "1", "1", "1", "1", "0"], + ["1", "1", "1", "0", "1", "1", "1"], + ["0", "1", "1", "1", "1", "1", "0"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "0", "1", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_117.json b/lib/data/levels/level_117.json new file mode 100644 index 0000000..d26aac9 --- /dev/null +++ b/lib/data/levels/level_117.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "1", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["0", "1", "0", "1", "0", "1", "0"], + ["1", "1", "1", "0", "1", "1", "1"], + ["1", "1", "0", "1", "0", "1", "1"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_118.json b/lib/data/levels/level_118.json new file mode 100644 index 0000000..996da53 --- /dev/null +++ b/lib/data/levels/level_118.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "0", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["0", "0", "1", "1", "1", "0", "0"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "0", "1", "0", "1", "1"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "0", "1", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_119.json b/lib/data/levels/level_119.json new file mode 100644 index 0000000..7632352 --- /dev/null +++ b/lib/data/levels/level_119.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "0", "0", "0", "x", "x"], + ["x", "x", "1", "1", "1", "x", "x"], + ["1", "1", "1", "1", "1", "1", "1"], + ["1", "1", "1", "1", "1", "1", "1"], + ["0", "1", "1", "1", "1", "1", "0"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "0", "1", "0", "x", "x"] + ] +} \ No newline at end of file diff --git a/lib/data/levels/level_120.json b/lib/data/levels/level_120.json new file mode 100644 index 0000000..2e0616d --- /dev/null +++ b/lib/data/levels/level_120.json @@ -0,0 +1,11 @@ +{ + "board": [ + ["x", "x", "1", "1", "0", "x", "x"], + ["x", "x", "0", "1", "1", "x", "x"], + ["0", "1", "1", "1", "1", "1", "1"], + ["0", "1", "1", "1", "1", "1", "1"], + ["0", "1", "1", "1", "1", "1", "0"], + ["x", "x", "1", "1", "1", "x", "x"], + ["x", "x", "1", "0", "0", "x", "x"] + ] +} \ No newline at end of file From 11b56308ec5ec048e67fe5e25043043c47cdbf85 Mon Sep 17 00:00:00 2001 From: Gleb Shalimov Date: Sat, 28 Mar 2026 11:03:27 +0300 Subject: [PATCH 2/5] up version --- CHANGELOG.md | 6 ++++++ ios/Runner.xcodeproj/project.pbxproj | 12 ++++++------ pubspec.yaml | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05cbef2..dc5daeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [1.11.0] + +#### New Features + +- Added 10 new game levels (111–120). + ## [1.10.0] #### New Features diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 8db0ceb..d934719 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -495,7 +495,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = G4KB5U6326; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -505,7 +505,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.10.0; + MARKETING_VERSION = 1.11.0; PRODUCT_BUNDLE_IDENTIFIER = com.khlebobul.pegma; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -683,7 +683,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = G4KB5U6326; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -693,7 +693,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.10.0; + MARKETING_VERSION = 1.11.0; PRODUCT_BUNDLE_IDENTIFIER = com.khlebobul.pegma; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -709,7 +709,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = G4KB5U6326; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -719,7 +719,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.10.0; + MARKETING_VERSION = 1.11.0; PRODUCT_BUNDLE_IDENTIFIER = com.khlebobul.pegma; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/pubspec.yaml b/pubspec.yaml index e739171..c16cf1b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: pegma description: "A free and cross-platform version of the classic Peg solitaire! Enjoy the timeless puzzle on your mobile device!" publish_to: 'none' -version: 1.10.0+33 +version: 1.11.0+34 environment: sdk: ^3.8.1 From 2347db34d8f082ce2cf7a8969af9e84378f68e0b Mon Sep 17 00:00:00 2001 From: Gleb Shalimov Date: Sat, 28 Mar 2026 16:33:20 +0300 Subject: [PATCH 3/5] updated solvability test --- devtools_options.yaml | 3 + test/levels_solvability_test.dart | 290 +++++++++++------------------- 2 files changed, 109 insertions(+), 184 deletions(-) create mode 100644 devtools_options.yaml diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/test/levels_solvability_test.dart b/test/levels_solvability_test.dart index f8cb21c..fdd25ff 100644 --- a/test/levels_solvability_test.dart +++ b/test/levels_solvability_test.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -61,7 +60,13 @@ void main() { // Check if level is solvable final solver = PegSolitaireSolver(board); + final stopwatch = Stopwatch()..start(); final isSolvable = solver.solve(); + stopwatch.stop(); + + final elapsed = stopwatch.elapsedMilliseconds; + final status = isSolvable ? '✓' : '✗'; + debugPrint('$status level_$levelId.json — ${elapsed}ms'); if (isSolvable) { solvedCount++; @@ -91,216 +96,133 @@ void main() { }); } -/// Solver for Peg Solitaire game +/// Optimized solver using bitboard representation and center-biased move ordering class PegSolitaireSolver { final List> initialBoard; final int maxDepth; - final Set _visitedStates = {}; - PegSolitaireSolver(this.initialBoard, {this.maxDepth = 1000}); + late final int _initialState; + late final int _initialPegCount; + late final List<_BitMove> _allMoves; + final Set _visitedStates = {}; - /// Attempts to solve the puzzle using backtracking - bool solve() { - final board = _copyBoard(initialBoard); - return _solveRecursive(board, 0); + PegSolitaireSolver(this.initialBoard, {this.maxDepth = 1000}) { + _precompute(); } - /// Recursive backtracking solver - bool _solveRecursive(List> board, int depth) { - // Check if we've exceeded max depth (prevent infinite recursion) - if (depth > maxDepth) { - return false; - } - - // Check win condition: only one peg left - final pegsCount = _countPegs(board); - if (pegsCount == 1) { - return true; - } - - // Check if no moves are possible - final allMoves = _getAllPossibleMoves(board); - if (allMoves.isEmpty) { - return false; + void _precompute() { + final rows = initialBoard.length; + final cols = initialBoard[0].length; + + // Map each active cell to a bit index + final cellIndex = >{}; + final cellRows = []; + final cellCols = []; + double sumR = 0, sumC = 0; + int activeCount = 0; + + for (int r = 0; r < rows; r++) { + cellIndex[r] = {}; + for (int c = 0; c < cols; c++) { + if (initialBoard[r][c] != 'x') { + cellIndex[r]![c] = activeCount; + cellRows.add(r); + cellCols.add(c); + sumR += r; + sumC += c; + activeCount++; + } + } } - // Create state signature to avoid revisiting same states - final stateSignature = _getBoardSignature(board); - if (_visitedStates.contains(stateSignature)) { - return false; - } - _visitedStates.add(stateSignature); + assert(activeCount <= 63, 'Board too large for bitboard solver'); - // Try each possible move - for (final move in allMoves) { - // Make the move - _makeMove(board, move); + final centerR = sumR / activeCount; + final centerC = sumC / activeCount; - // Recursively try to solve - if (_solveRecursive(board, depth + 1)) { - return true; + // Build initial state bitmask + int state = 0; + int pegCount = 0; + for (int i = 0; i < activeCount; i++) { + if (initialBoard[cellRows[i]][cellCols[i]] == '1') { + state |= (1 << i); + pegCount++; } - - // Undo the move (backtrack) - _undoMove(board, move); } - - return false; - } - - /// Get all possible moves from current board state - List _getAllPossibleMoves(List> board) { - final moves = []; - - for (int r = 0; r < board.length; r++) { - for (int c = 0; c < board[r].length; c++) { - if (board[r][c] == '1') { - // Check all four directions - final directions = [ - const Point(0, 2), // right - const Point(0, -2), // left - const Point(2, 0), // down - const Point(-2, 0), // up - ]; - - for (final dir in directions) { - final targetRow = r + dir.x; - final targetCol = c + dir.y; - final middleRow = r + dir.x ~/ 2; - final middleCol = c + dir.y ~/ 2; - - if (_isValidMove( - board, - r, - c, - targetRow, - targetCol, - middleRow, - middleCol, - )) { - moves.add( - Move( - fromRow: r, - fromCol: c, - toRow: targetRow, - toCol: targetCol, - middleRow: middleRow, - middleCol: middleCol, - ), - ); - } - } + _initialState = state; + _initialPegCount = pegCount; + + // Precompute all possible jump templates sorted by target centrality + const directions = [ + [0, 2], [0, -2], [2, 0], [-2, 0], + ]; + + _allMoves = []; + for (int i = 0; i < activeCount; i++) { + final r = cellRows[i]; + final c = cellCols[i]; + for (final dir in directions) { + final mr = r + dir[0] ~/ 2; + final mc = c + dir[1] ~/ 2; + final tr = r + dir[0]; + final tc = c + dir[1]; + final midIdx = cellIndex[mr]?[mc]; + final tarIdx = cellIndex[tr]?[tc]; + if (midIdx != null && tarIdx != null) { + final dr = tr - centerR; + final dc = tc - centerC; + _allMoves.add(_BitMove( + fromBit: 1 << i, + middleBit: 1 << midIdx, + targetBit: 1 << tarIdx, + targetDist: dr * dr + dc * dc, + )); } } } - return moves; + // Moves toward center first — dramatically prunes search tree + _allMoves.sort((a, b) => a.targetDist.compareTo(b.targetDist)); } - /// Check if a move is valid - bool _isValidMove( - List> board, - int fromRow, - int fromCol, - int toRow, - int toCol, - int middleRow, - int middleCol, - ) { - // Check bounds - if (toRow < 0 || - toRow >= board.length || - toCol < 0 || - toCol >= board[0].length || - middleRow < 0 || - middleRow >= board.length || - middleCol < 0 || - middleCol >= board[0].length) { - return false; - } - - // Target must be empty (0 or eaten) - if (board[toRow][toCol] != '0' && board[toRow][toCol] != 'eaten') { - return false; - } - - // Middle must have a peg - if (board[middleRow][middleCol] != '1') { - return false; - } - - // Source must have a peg - if (board[fromRow][fromCol] != '1') { - return false; - } - - // Can't move to inactive cells - if (board[toRow][toCol] == 'x') { - return false; - } - - return true; - } - - /// Make a move on the board - void _makeMove(List> board, Move move) { - board[move.toRow][move.toCol] = '1'; - board[move.fromRow][move.fromCol] = 'eaten'; - board[move.middleRow][move.middleCol] = 'eaten'; - } - - /// Undo a move on the board - void _undoMove(List> board, Move move) { - board[move.fromRow][move.fromCol] = '1'; - board[move.middleRow][move.middleCol] = '1'; - board[move.toRow][move.toCol] = '0'; + bool solve() { + _visitedStates.clear(); + return _solveRecursive(_initialState, _initialPegCount, 0); } - /// Count number of pegs on the board - int _countPegs(List> board) { - int count = 0; - for (final row in board) { - for (final cell in row) { - if (cell == '1') { - count++; + bool _solveRecursive(int state, int pegCount, int depth) { + if (depth > maxDepth) return false; + if (pegCount == 1) return true; + if (_visitedStates.contains(state)) return false; + _visitedStates.add(state); + + for (final move in _allMoves) { + // from has peg, middle has peg, target is empty + if ((state & move.fromBit) != 0 && + (state & move.middleBit) != 0 && + (state & move.targetBit) == 0) { + final newState = + (state & ~move.fromBit & ~move.middleBit) | move.targetBit; + if (_solveRecursive(newState, pegCount - 1, depth + 1)) { + return true; } } } - return count; - } - - /// Create a signature of the board state for duplicate detection - String _getBoardSignature(List> board) { - final buffer = StringBuffer(); - for (final row in board) { - for (final cell in row) { - buffer.write(cell); - } - } - return buffer.toString(); - } - /// Create a deep copy of the board - List> _copyBoard(List> board) { - return board.map((row) => List.from(row)).toList(); + return false; } } -/// Represents a move in the game -class Move { - final int fromRow; - final int fromCol; - final int toRow; - final int toCol; - final int middleRow; - final int middleCol; - - Move({ - required this.fromRow, - required this.fromCol, - required this.toRow, - required this.toCol, - required this.middleRow, - required this.middleCol, +class _BitMove { + final int fromBit; + final int middleBit; + final int targetBit; + final double targetDist; + + const _BitMove({ + required this.fromBit, + required this.middleBit, + required this.targetBit, + required this.targetDist, }); } From 9b3016cc431f00523863496948ef51f785d3a9d0 Mon Sep 17 00:00:00 2001 From: Gleb Shalimov Date: Sat, 28 Mar 2026 16:33:30 +0300 Subject: [PATCH 4/5] fix levels --- lib/data/levels/level_118.json | 2 +- lib/data/levels/level_120.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/data/levels/level_118.json b/lib/data/levels/level_118.json index 996da53..45ed1f7 100644 --- a/lib/data/levels/level_118.json +++ b/lib/data/levels/level_118.json @@ -1,6 +1,6 @@ { "board": [ - ["x", "x", "0", "0", "0", "x", "x"], + ["x", "x", "0", "1", "0", "x", "x"], ["x", "x", "1", "1", "1", "x", "x"], ["0", "0", "1", "1", "1", "0", "0"], ["1", "1", "1", "1", "1", "1", "1"], diff --git a/lib/data/levels/level_120.json b/lib/data/levels/level_120.json index 2e0616d..7a80c03 100644 --- a/lib/data/levels/level_120.json +++ b/lib/data/levels/level_120.json @@ -1,7 +1,7 @@ { "board": [ ["x", "x", "1", "1", "0", "x", "x"], - ["x", "x", "0", "1", "1", "x", "x"], + ["x", "x", "0", "1", "0", "x", "x"], ["0", "1", "1", "1", "1", "1", "1"], ["0", "1", "1", "1", "1", "1", "1"], ["0", "1", "1", "1", "1", "1", "0"], From d12f1bf3c855152bf2152d16f535182b57a6d286 Mon Sep 17 00:00:00 2001 From: Gleb Shalimov Date: Sat, 28 Mar 2026 16:43:19 +0300 Subject: [PATCH 5/5] up version --- ios/Runner.xcodeproj/project.pbxproj | 6 +++--- pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index d934719..42b1620 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -495,7 +495,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEVELOPMENT_TEAM = G4KB5U6326; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -683,7 +683,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEVELOPMENT_TEAM = G4KB5U6326; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -709,7 +709,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEVELOPMENT_TEAM = G4KB5U6326; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; diff --git a/pubspec.yaml b/pubspec.yaml index c16cf1b..58d59b5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: pegma description: "A free and cross-platform version of the classic Peg solitaire! Enjoy the timeless puzzle on your mobile device!" publish_to: 'none' -version: 1.11.0+34 +version: 1.11.0+35 environment: sdk: ^3.8.1