Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 23-add-timer
  • 65-update-icons
  • 82-fix-colors
  • 84-improve-app-metadata
  • master
  • Release_0.0.16_16
  • Release_0.0.17_17
  • Release_0.0.18_18
  • Release_0.0.19_19
  • Release_0.0.20_20
  • Release_0.0.21_21
  • Release_0.0.22_22
  • Release_0.0.23_23
  • Release_0.0.24_24
  • Release_0.0.25_25
  • Release_0.0.26_26
  • Release_0.0.27_27
  • Release_0.0.28_28
  • Release_0.0.29_29
  • Release_0.0.30_30
  • Release_0.0.31_31
  • Release_0.0.32_32
  • Release_0.0.33_33
  • Release_0.0.34_34
  • Release_0.0.35_35
  • Release_0.0.36_36
  • Release_0.0.37_37
  • Release_0.0.38_38
  • Release_0.0.39_39
  • Release_0.0.40_40
  • Release_0.0.41_41
  • Release_0.0.42_42
  • Release_0.0.43_43
  • Release_0.0.44_44
  • Release_0.0.45_45
  • Release_0.0.46_46
  • Release_0.0.47_47
  • Release_0.0.48_48
  • Release_0.1.0_49
  • Release_0.1.10_59
  • Release_0.1.11_60
  • Release_0.1.12_61
  • Release_0.1.13_62
  • Release_0.1.14_63
  • Release_0.1.15_64
  • Release_0.1.16_65
  • Release_0.1.17_66
  • Release_0.1.18_67
  • Release_0.1.19_68
  • Release_0.1.1_50
  • Release_0.1.20_69
  • Release_0.1.21_70
  • Release_0.1.22_71
  • Release_0.1.2_51
  • Release_0.1.3_52
  • Release_0.1.4_53
  • Release_0.1.5_54
  • Release_0.1.6_55
  • Release_0.1.7_56
  • Release_0.1.8_57
  • Release_0.1.9_58
  • Release_0.10.0_87
  • Release_0.2.0_72
  • Release_0.2.1_73
  • Release_0.3.0_74
  • Release_0.3.1_75
  • Release_0.4.0_76
  • Release_0.4.1_77
  • Release_0.5.0_78
  • Release_0.5.1_79
  • Release_0.5.2_80
  • Release_0.6.0_81
  • Release_0.7.0_82
  • Release_0.8.0_83
  • Release_0.9.0_84
  • Release_0.9.1_85
  • Release_0.9.2_86
77 results

Target

Select target project
  • android/org.benoitharrault.sudoku
1 result
Select Git revision
  • 23-add-timer
  • 65-update-icons
  • 82-fix-colors
  • 84-improve-app-metadata
  • master
  • Release_0.0.16_16
  • Release_0.0.17_17
  • Release_0.0.18_18
  • Release_0.0.19_19
  • Release_0.0.20_20
  • Release_0.0.21_21
  • Release_0.0.22_22
  • Release_0.0.23_23
  • Release_0.0.24_24
  • Release_0.0.25_25
  • Release_0.0.26_26
  • Release_0.0.27_27
  • Release_0.0.28_28
  • Release_0.0.29_29
  • Release_0.0.30_30
  • Release_0.0.31_31
  • Release_0.0.32_32
  • Release_0.0.33_33
  • Release_0.0.34_34
  • Release_0.0.35_35
  • Release_0.0.36_36
  • Release_0.0.37_37
  • Release_0.0.38_38
  • Release_0.0.39_39
  • Release_0.0.40_40
  • Release_0.0.41_41
  • Release_0.0.42_42
  • Release_0.0.43_43
  • Release_0.0.44_44
  • Release_0.0.45_45
  • Release_0.0.46_46
  • Release_0.0.47_47
  • Release_0.0.48_48
  • Release_0.1.0_49
  • Release_0.1.10_59
  • Release_0.1.11_60
  • Release_0.1.12_61
  • Release_0.1.13_62
  • Release_0.1.14_63
  • Release_0.1.15_64
  • Release_0.1.16_65
  • Release_0.1.17_66
  • Release_0.1.18_67
  • Release_0.1.19_68
  • Release_0.1.1_50
  • Release_0.1.20_69
  • Release_0.1.21_70
  • Release_0.1.22_71
  • Release_0.1.2_51
  • Release_0.1.3_52
  • Release_0.1.4_53
  • Release_0.1.5_54
  • Release_0.1.6_55
  • Release_0.1.7_56
  • Release_0.1.8_57
  • Release_0.1.9_58
  • Release_0.10.0_87
  • Release_0.2.0_72
  • Release_0.2.1_73
  • Release_0.3.0_74
  • Release_0.3.1_75
  • Release_0.4.0_76
  • Release_0.4.1_77
  • Release_0.5.0_78
  • Release_0.5.1_79
  • Release_0.5.2_80
  • Release_0.6.0_81
  • Release_0.7.0_82
  • Release_0.8.0_83
  • Release_0.9.0_84
  • Release_0.9.1_85
  • Release_0.9.2_86
77 results
Show changes
Showing
with 398 additions and 280 deletions
assets/skins/nature_9.png

10.5 KiB | W: 0px | H: 0px

assets/skins/nature_9.png

10.6 KiB | W: 0px | H: 0px

assets/skins/nature_9.png
assets/skins/nature_9.png
assets/skins/nature_9.png
assets/skins/nature_9.png
  • 2-up
  • Swipe
  • Onion skin
Upgrade flutter framework and dependencies, clean / update some code
fastlane/metadata/android/en-US/images/icon.png

16.7 KiB | W: 0px | H: 0px

fastlane/metadata/android/en-US/images/icon.png

16.9 KiB | W: 0px | H: 0px

fastlane/metadata/android/en-US/images/icon.png
fastlane/metadata/android/en-US/images/icon.png
fastlane/metadata/android/en-US/images/icon.png
fastlane/metadata/android/en-US/images/icon.png
  • 2-up
  • Swipe
  • Onion skin
Mise à jour du framework Flutter et de ses dépendances, améliorations / corrections de code
......@@ -9,8 +9,18 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
BASE_DIR="$(dirname "${CURRENT_DIR}")"
SOURCE="${CURRENT_DIR}/icon.svg"
SOURCE_FASTLANE="${CURRENT_DIR}/featureGraphic.svg"
OPTIPNG_OPTIONS="-preserve -quiet -o7"
if [ ! -f "${SOURCE}" ]; then
echo "Missing file: ${SOURCE}"
fi
if [ ! -f "${SOURCE_FASTLANE}" ]; then
echo "Missing file: ${SOURCE_FASTLANE}"
fi
# optimize svg
cp ${SOURCE} ${SOURCE}.tmp
scour \
......@@ -19,6 +29,7 @@ scour \
--enable-viewboxing \
--enable-comment-stripping \
--nindent=4 \
--quiet \
-i ${SOURCE}.tmp \
-o ${SOURCE}
rm ${SOURCE}.tmp
......@@ -28,6 +39,8 @@ function build_icon() {
ICON_SIZE="$1"
TARGET="$2"
echo "Building ${TARGET}"
TARGET_PNG="${TARGET}.png"
inkscape \
......@@ -45,7 +58,7 @@ function build_fastlane_image() {
HEIGHT="$2"
TARGET="$3"
SOURCE_FASTLANE="${CURRENT_DIR}/featureGraphic.svg"
echo "Building ${TARGET}"
cp ${SOURCE_FASTLANE} ${SOURCE_FASTLANE}.tmp
scour \
......@@ -54,6 +67,7 @@ function build_fastlane_image() {
--enable-viewboxing \
--enable-comment-stripping \
--nindent=4 \
--quiet \
-i ${SOURCE_FASTLANE}.tmp \
-o ${SOURCE_FASTLANE}
rm ${SOURCE_FASTLANE}.tmp
......
......@@ -7,8 +7,59 @@ command -v optipng >/dev/null 2>&1 || { echo >&2 "I require optipng but it's not
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
BASE_DIR="$(dirname "${CURRENT_DIR}")"
ASSETS_DIR="${BASE_DIR}/assets"
OPTIPNG_OPTIONS="-preserve -quiet -o7"
ICON_SIZE=192
#######################################################
# Game images
AVAILABLE_GAME_IMAGES="
button_back
button_start
button_help
button_show_conflicts
game_win
placeholder
cell_empty
"
# Settings images
AVAILABLES_GAME_SETTINGS="
level:easy,medium,hard,nightmare
size:2x2,3x2,3x3,4x4
"
# Skins
AVAILABLE_SKINS="
default
food
monsters
nature
"
# Images per skin
SKIN_IMAGES="
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"
#######################################################
# optimize svg
function optimize_svg() {
......@@ -21,6 +72,7 @@ function optimize_svg() {
--enable-viewboxing \
--enable-comment-stripping \
--nindent=4 \
--quiet \
-i ${SOURCE}.tmp \
-o ${SOURCE}
rm ${SOURCE}.tmp
......@@ -28,10 +80,16 @@ function optimize_svg() {
# build icons
function build_icon() {
ICON_SIZE=192
SOURCE="$1"
TARGET="$2"
echo "Building ${TARGET}"
if [ ! -f "${SOURCE}" ]; then
echo "Missing file: ${SOURCE}"
exit 1
fi
optimize_svg "${SOURCE}"
inkscape \
......@@ -43,36 +101,56 @@ function build_icon() {
optipng ${OPTIPNG_OPTIONS} ${TARGET}
}
function build_settings_icons() {
INPUT_STRING="$1"
SETTING_NAME="$(echo "${INPUT_STRING}" | cut -d":" -f1)"
SETTING_VALUES="$(echo "${INPUT_STRING}" | cut -d":" -f2 | tr "," " ")"
for SETTING_VALUE in ${SETTING_VALUES}
do
SETTING_CODE="${SETTING_NAME}_${SETTING_VALUE}"
build_icon ${CURRENT_DIR}/${SETTING_CODE}.svg ${ASSETS_DIR}/icons/${SETTING_CODE}.png
done
}
function build_icon_for_skin() {
SKIN_CODE="$1"
build_icon ${CURRENT_DIR}/skin_${SKIN_CODE}.svg ${BASE_DIR}/assets/icons/skin_${SKIN_CODE}.png
for VALUE in {1..16};
# skin main image
build_icon ${CURRENT_DIR}/skin_${SKIN_CODE}.svg ${ASSETS_DIR}/icons/skin_${SKIN_CODE}.png
# skin images
for SKIN_IMAGE in ${SKIN_IMAGES}
do
if [ -f "${CURRENT_DIR}/skins/${SKIN_CODE}/${VALUE}.svg" ]; then
build_icon ${CURRENT_DIR}/skins/${SKIN_CODE}/${VALUE}.svg ${BASE_DIR}/assets/skins/${SKIN_CODE}_${VALUE}.png
fi
build_icon ${CURRENT_DIR}/skins/${SKIN_CODE}/${SKIN_IMAGE}.svg ${ASSETS_DIR}/skins/${SKIN_CODE}_${SKIN_IMAGE}.png
done
}
# Game icons
build_icon ${CURRENT_DIR}/button_back.svg ${BASE_DIR}/assets/icons/button_back.png
build_icon ${CURRENT_DIR}/button_help.svg ${BASE_DIR}/assets/icons/button_help.png
build_icon ${CURRENT_DIR}/button_show_conflicts.svg ${BASE_DIR}/assets/icons/button_show_conflicts.png
build_icon ${CURRENT_DIR}/button_start.svg ${BASE_DIR}/assets/icons/button_start.png
build_icon ${CURRENT_DIR}/difficulty_easy.svg ${BASE_DIR}/assets/icons/difficulty_easy.png
build_icon ${CURRENT_DIR}/difficulty_medium.svg ${BASE_DIR}/assets/icons/difficulty_medium.png
build_icon ${CURRENT_DIR}/difficulty_hard.svg ${BASE_DIR}/assets/icons/difficulty_hard.png
build_icon ${CURRENT_DIR}/difficulty_nightmare.svg ${BASE_DIR}/assets/icons/difficulty_nightmare.png
build_icon ${CURRENT_DIR}/game_win.svg ${BASE_DIR}/assets/icons/game_win.png
build_icon ${CURRENT_DIR}/size_2x2.svg ${BASE_DIR}/assets/icons/size_2x2.png
build_icon ${CURRENT_DIR}/size_3x2.svg ${BASE_DIR}/assets/icons/size_3x2.png
build_icon ${CURRENT_DIR}/size_3x3.svg ${BASE_DIR}/assets/icons/size_3x3.png
build_icon ${CURRENT_DIR}/size_4x4.svg ${BASE_DIR}/assets/icons/size_4x4.png
build_icon ${CURRENT_DIR}/skins/empty.svg ${BASE_DIR}/assets/skins/empty.png
#######################################################
# Skins
build_icon_for_skin "default"
build_icon_for_skin "food"
build_icon_for_skin "monsters"
build_icon_for_skin "nature"
# Create output folders
mkdir -p ${ASSETS_DIR}/icons
mkdir -p ${ASSETS_DIR}/skins
# Delete existing generated images
find ${ASSETS_DIR}/icons -type f -name "*.png" -delete
find ${ASSETS_DIR}/skins -type f -name "*.png" -delete
# build game images
for GAME_IMAGE in ${AVAILABLE_GAME_IMAGES}
do
build_icon ${CURRENT_DIR}/${GAME_IMAGE}.svg ${ASSETS_DIR}/icons/${GAME_IMAGE}.png
done
# build settings images
for GAME_SETTING in ${AVAILABLES_GAME_SETTINGS}
do
build_settings_icons "${GAME_SETTING}"
done
# build skins images
for SKIN in ${AVAILABLE_SKINS}
do
build_icon_for_skin "${SKIN}"
done
File moved
This diff is collapsed.
File moved
File moved
File moved
<?xml version="1.0" encoding="UTF-8"?>
<svg enable-background="new 0 0 100 100" version="1.1" viewBox="0 0 102 102" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"/>
This diff is collapsed.
......@@ -12,8 +12,8 @@ class Cell {
bool isAnimated = false;
Cell(
@required this.value,
@required this.isFixed,
this.value,
this.isFixed,
);
/*
......@@ -40,15 +40,13 @@ class Cell {
),
),
onTap: () {
if (col != null && row != null) {
if (col != myProvider.currentCellCol || row != myProvider.currentCellRow) {
myProvider.selectCell(col, row);
} else {
myProvider.selectCell(null, null);
}
if (col != myProvider.currentCellCol || row != myProvider.currentCellRow) {
myProvider.selectCell(col, row);
} else {
myProvider.selectCell(null, null);
}
},
)
),
);
}
......@@ -61,56 +59,53 @@ class Cell {
}
String imageAsset = this.getImageAssetName(myProvider);
Color backgroundColor = Colors.grey[200];
Color backgroundColor = Colors.grey.shade200;
if (
myProvider.showConflicts
&& myProvider.currentCellCol != null
&& myProvider.currentCellRow != null
) {
if (myProvider.showConflicts &&
myProvider.currentCellCol != null &&
myProvider.currentCellRow != null) {
List cells = myProvider.cells;
int blockSizeHorizontal = myProvider.blockSizeHorizontal;
int blockSizeVertical = myProvider.blockSizeVertical;
if (!BoardUtils.isValueAllowed(cells, blockSizeHorizontal, blockSizeVertical, myProvider.currentCellCol, myProvider.currentCellRow, this.value)) {
backgroundColor = Colors.pink[100];
if (!BoardUtils.isValueAllowed(cells, blockSizeHorizontal, blockSizeVertical,
myProvider.currentCellCol, myProvider.currentCellRow, this.value)) {
backgroundColor = Colors.pink.shade100;
}
}
return Container(
decoration: BoxDecoration(
color: backgroundColor,
border: Border.all(
color: Colors.black,
width: 2,
),
),
child: GestureDetector(
child: Image(
image: AssetImage(imageAsset),
fit: BoxFit.fill
decoration: BoxDecoration(
color: backgroundColor,
border: Border.all(
color: Colors.black,
width: 2,
),
),
onTap: () {
if (myProvider.currentCellCol != null && myProvider.currentCellRow != null) {
myProvider.updateCellValue(myProvider.currentCellCol, myProvider.currentCellRow, this.value);
}
myProvider.selectCell(null, null);
if (BoardUtils.checkBoardIsSolved(myProvider)) {
BoardAnimate.startAnimation(myProvider, 'win');
}
},
)
);
child: GestureDetector(
child: Image(image: AssetImage(imageAsset), fit: BoxFit.fill),
onTap: () {
if (myProvider.currentCellCol != null && myProvider.currentCellRow != null) {
myProvider.updateCellValue(
myProvider.currentCellCol, myProvider.currentCellRow, this.value);
}
myProvider.selectCell(null, null);
if (BoardUtils.checkBoardIsSolved(myProvider)) {
BoardAnimate.startAnimation(myProvider, 'win');
}
},
));
}
/*
* Compute image asset name, from skin and cell value/state
*/
String getImageAssetName(Data myProvider) {
String imageAsset = 'assets/skins/empty.png';
String imageAsset = 'assets/icons/cell_empty.png';
if (this.value > 0) {
int cellValue = myProvider.getTranslatedValueForDisplay(this.value);
imageAsset = 'assets/skins/' + myProvider.skin + '_' + cellValue.toString() + '.png';
imageAsset =
'assets/skins/' + myProvider.parameterSkin + '_' + cellValue.toString() + '.png';
}
return imageAsset;
......@@ -118,14 +113,14 @@ class Cell {
// Compute cell background color, from cell state
Color getBackgroundColor(Data myProvider) {
Color editableCellColor = Colors.grey[100];
Color editableCellColorConflict = Colors.pink[100];
Color fixedCellColor = Colors.grey[300];
Color fixedCellColorConflict = Colors.pink[200];
Color editableSelectedValueColor = Colors.green[100];
Color fixedSelectedValueColor = Colors.green[300];
Color editableAnimated = Colors.green[200];
Color fixedAnimated = Colors.green[300];
Color editableCellColor = Colors.grey.shade100;
Color editableCellColorConflict = Colors.pink.shade100;
Color fixedCellColor = Colors.grey.shade300;
Color fixedCellColorConflict = Colors.pink.shade200;
Color editableSelectedValueColor = Colors.green.shade100;
Color fixedSelectedValueColor = Colors.green.shade300;
Color editableAnimated = Colors.green.shade200;
Color fixedAnimated = Colors.green.shade300;
Color backgroundColor = editableCellColor;
......@@ -175,14 +170,14 @@ class Cell {
// Reduce cell border width on big boards
int boardSize = blockSizeVertical * blockSizeHorizontal;
if (boardSize > 8) {
cellBorderWidth = 2;
if (boardSize > 10) {
cellBorderWidth = 1;
}
cellBorderWidth = 2;
if (boardSize > 10) {
cellBorderWidth = 1;
}
}
if (!myProvider.gameIsRunning) {
cellBorderColor = Colors.green[700];
cellBorderColor = Colors.green.shade700;
}
Border borders = Border.all(
......@@ -193,10 +188,25 @@ class Cell {
// Update cell borders if not currently selected cell
if (col != myProvider.currentCellCol || row != myProvider.currentCellRow) {
borders = Border(
top: BorderSide(width: cellBorderWidth, color: ((row % blockSizeVertical) == 0) ? cellBorderDarkColor : cellBorderLightColor),
left: BorderSide(width: cellBorderWidth, color: ((col % blockSizeHorizontal) == 0) ? cellBorderDarkColor : cellBorderLightColor),
right: BorderSide(width: cellBorderWidth, color: (((col + 1) % blockSizeHorizontal) == 0) ? cellBorderDarkColor : cellBorderLightColor),
bottom: BorderSide(width: cellBorderWidth, color: (((row + 1) % blockSizeVertical) == 0) ? cellBorderDarkColor : cellBorderLightColor),
top: BorderSide(
width: cellBorderWidth,
color:
((row % blockSizeVertical) == 0) ? cellBorderDarkColor : cellBorderLightColor),
left: BorderSide(
width: cellBorderWidth,
color: ((col % blockSizeHorizontal) == 0)
? cellBorderDarkColor
: cellBorderLightColor),
right: BorderSide(
width: cellBorderWidth,
color: (((col + 1) % blockSizeHorizontal) == 0)
? cellBorderDarkColor
: cellBorderLightColor),
bottom: BorderSide(
width: cellBorderWidth,
color: (((row + 1) % blockSizeVertical) == 0)
? cellBorderDarkColor
: cellBorderLightColor),
);
}
......
......@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
import '../provider/data.dart';
class Board {
static Container buildGameBoard(Data myProvider) {
Color borderColor = Colors.black;
......@@ -30,22 +29,12 @@ class Board {
int boardSize = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
List cells = myProvider.cells;
return Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
for (var row = 0; row < boardSize; row++)
TableRow(children: [
for (var col = 0; col < boardSize; col++)
Column(children: [
cells[row][col].widget(
myProvider,
row,
col
)
]),
]),
]
);
return Table(defaultColumnWidth: IntrinsicColumnWidth(), children: [
for (var row = 0; row < boardSize; row++)
TableRow(children: [
for (var col = 0; col < boardSize; col++)
Column(children: [cells[row][col].widget(myProvider, row, col)]),
]),
]);
}
}
......@@ -9,7 +9,6 @@ import '../utils/board_utils.dart';
import '../utils/game_utils.dart';
class Game {
static Container buildGameWidget(Data myProvider) {
bool gameIsFinished = BoardUtils.checkBoardIsSolved(myProvider);
......@@ -21,8 +20,8 @@ class Game {
Board.buildGameBoard(myProvider),
SizedBox(height: 2),
gameIsFinished
? Game.buildEndGameMessage(myProvider)
: Game.buildSelectCellValueBar(myProvider),
? Game.buildEndGameMessage(myProvider)
: Game.buildSelectCellValueBar(myProvider),
],
),
);
......@@ -31,10 +30,11 @@ class Game {
static Container buildSelectCellValueBar(Data myProvider) {
List cells = myProvider.cells;
Color borderColor = Colors.blue;
bool isCellSelected = (myProvider.currentCellCol != null && myProvider.currentCellRow != null);
bool isUpdatableCellSelected = isCellSelected ? !myProvider.cells[myProvider.currentCellRow][myProvider.currentCellCol].isFixed : false;
bool isCellSelected =
(myProvider.currentCellCol != null && myProvider.currentCellRow != null);
bool isUpdatableCellSelected = isCellSelected
? !cells[myProvider.currentCellRow ?? 0][myProvider.currentCellCol ?? 0].isFixed
: false;
int maxValue = myProvider.blockSizeHorizontal * myProvider.blockSizeVertical;
int maxItemsPerLine = 10;
......@@ -44,35 +44,31 @@ class Game {
return Container(
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
for (var lineIndex = 0; lineIndex < linesCount; lineIndex++)
TableRow(
children: [
for (
var value = lineIndex * itemsCountPerLine;
value < (lineIndex + 1) * itemsCountPerLine;
value++
)
for (var value = lineIndex * itemsCountPerLine;
value < (lineIndex + 1) * itemsCountPerLine;
value++)
Column(
children: [
Cell(
isUpdatableCellSelected ? (value <= maxValue ? value : -1) : -1,
false
).widgetUpdateValue(myProvider)
]
Cell(isUpdatableCellSelected ? (value <= maxValue ? value : -1) : -1,
false)
.widgetUpdateValue(myProvider)
],
),
]
],
),
]
],
),
);
}
static FlatButton buildRestartGameButton(Data myProvider) {
return FlatButton(
static TextButton buildRestartGameButton(Data myProvider) {
return TextButton(
child: Container(
child: Image(
image: AssetImage('assets/icons/button_back.png'),
......@@ -85,29 +81,35 @@ class Game {
static Container buildEndGameMessage(Data myProvider) {
Image decorationImage = Image(
image: AssetImage(
'assets/icons/game_win.png'
),
fit: BoxFit.fill
image: AssetImage('assets/icons/game_win.png'),
fit: BoxFit.fill,
);
return Container(
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
child: Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
TableRow(
children: [
Column(children: [ decorationImage ]),
Column(children: [ myProvider.animationInProgress ? decorationImage : buildRestartGameButton(myProvider) ]),
Column(children: [ decorationImage ]),
Column(
children: [decorationImage],
),
Column(
children: [
myProvider.animationInProgress
? decorationImage
: buildRestartGameButton(myProvider)
],
),
Column(
children: [decorationImage],
),
],
),
]
)
],
),
);
}
}
......@@ -4,23 +4,43 @@ import '../provider/data.dart';
import '../utils/game_utils.dart';
class Parameters {
static double separatorHeight = 2.0;
static double blockMargin = 3.0;
static double blockPadding = 2.0;
static Color buttonBackgroundColor = Colors.white;
static Color buttonBorderColorActive = Colors.blue;
static Color buttonBorderColorInactive = Colors.white;
static double buttonBorderWidth = 10.0;
static double buttonBorderRadius = 8.0;
static double buttonPadding = 0.0;
static double buttonMargin = 0.0;
static Container buildParametersSelector(Data myProvider) {
List<Widget> lines = [];
List parameters = myProvider.availableParameters;
for (var index = 0; index < parameters.length; index++) {
lines.add(Parameters.buildParameterSelector(myProvider, parameters[index]));
lines.add(SizedBox(height: Parameters.separatorHeight));
}
return Container(
padding: EdgeInsets.all(2),
margin: EdgeInsets.all(2),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Parameters.buildParameterSelector(myProvider, 'difficulty'),
SizedBox(height: 5),
Parameters.buildParameterSelector(myProvider, 'size'),
SizedBox(height: 5),
Parameters.buildParameterSelector(myProvider, 'skin'),
SizedBox(height: 5),
Parameters.buildStartGameButton(myProvider),
SizedBox(height: Parameters.separatorHeight),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: lines,
),
),
SizedBox(height: Parameters.separatorHeight),
Container(
child: Parameters.buildStartGameButton(myProvider),
),
],
),
);
......@@ -29,17 +49,13 @@ class Parameters {
static Container buildStartGameButton(Data myProvider) {
Column decorationImage = Column(
children: [
Image(
image: AssetImage('assets/icons/game_win.png'),
fit: BoxFit.fill
),
]
Image(image: AssetImage('assets/icons/placeholder.png'), fit: BoxFit.fill),
],
);
return Container(
margin: EdgeInsets.all(2),
padding: EdgeInsets.all(2),
margin: EdgeInsets.all(Parameters.blockMargin),
padding: EdgeInsets.all(Parameters.blockPadding),
child: Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
......@@ -48,7 +64,7 @@ class Parameters {
decorationImage,
Column(
children: [
FlatButton(
TextButton(
child: Container(
child: Image(
image: AssetImage('assets/icons/button_start.png'),
......@@ -57,19 +73,23 @@ class Parameters {
),
onPressed: () => GameUtils.startGame(myProvider),
),
]
],
),
decorationImage,
],
),
]
)
],
),
);
}
static Table buildParameterSelector(Data myProvider, String parameterCode) {
static Widget buildParameterSelector(Data myProvider, String parameterCode) {
List availableValues = myProvider.getParameterAvailableValues(parameterCode);
if (availableValues.length == 1) {
return SizedBox(height: 0.0);
}
return Table(
defaultColumnWidth: IntrinsicColumnWidth(),
children: [
......@@ -79,7 +99,7 @@ class Parameters {
Column(
children: [
_buildParameterButton(myProvider, parameterCode, availableValues[index])
]
],
),
],
),
......@@ -87,21 +107,25 @@ class Parameters {
);
}
static FlatButton _buildParameterButton(Data myProvider, String parameterCode, String parameterValue) {
static Widget _buildParameterButton(
Data myProvider, String parameterCode, String parameterValue) {
String currentValue = myProvider.getParameterValue(parameterCode).toString();
bool isActive = (parameterValue == currentValue);
String imageAsset = 'assets/icons/' + parameterCode + '_' + parameterValue + '.png';
return FlatButton(
padding: EdgeInsets.all(2),
return TextButton(
child: Container(
margin: EdgeInsets.all(Parameters.buttonMargin),
padding: EdgeInsets.all(Parameters.buttonPadding),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
color: Parameters.buttonBackgroundColor,
borderRadius: BorderRadius.circular(Parameters.buttonBorderRadius),
border: Border.all(
color: isActive ? Colors.blue : Colors.white,
width: 10,
color: isActive
? Parameters.buttonBorderColorActive
: Parameters.buttonBorderColorInactive,
width: Parameters.buttonBorderWidth,
),
),
child: Image(
......@@ -112,5 +136,4 @@ class Parameters {
onPressed: () => myProvider.setParameterValue(parameterCode, parameterValue),
);
}
}
......@@ -2,92 +2,101 @@ import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Data extends ChangeNotifier {
// Configuration available values
List _availableDifficultyLevels = ['easy', 'medium', 'hard', 'nightmare'];
List _availableSizes = ['2x2', '3x2', '3x3', '4x4'];
List _availableSkins = ['default', 'food', 'nature', 'monsters'];
List _availableParameters = ['level', 'size', 'skin'];
List _availableLevelValues = ['easy', 'medium', 'hard', 'nightmare'];
List _availableSizeValues = ['2x2', '3x2', '3x3', '4x4'];
List _availableSkinValues = ['default', 'food', 'nature', 'monsters'];
List _shufflableSkins = ['food', 'nature', 'monsters'];
List get availableDifficultyLevels => _availableDifficultyLevels;
List get availableSizes => _availableSizes;
List get availableSkins => _availableSkins;
List get availableParameters => _availableParameters;
List get availableLevelValues => _availableLevelValues;
List get availableSizeValues => _availableSizeValues;
List get availableSkinValues => _availableSkinValues;
// Application default configuration
String _level = null;
String _levelDefault = 'medium';
String _size = null;
String _sizeDefault = '3x3';
String _skin = null;
String _skinDefault = 'default';
String _parameterLevel = '';
String _parameterLevelDefault = 'medium';
String _parameterSize = '';
String _parameterSizeDefault = '3x3';
String _parameterSkin = '';
String _parameterSkinDefault = 'default';
// Application current configuration
String get parameterLevel => _parameterLevel;
String get parameterSize => _parameterSize;
String get parameterSkin => _parameterSkin;
// Game data
bool _assetsPreloaded = false;
bool _gameIsRunning = false;
bool _animationInProgress = false;
int _blockSizeVertical = null;
int _blockSizeHorizontal = null;
int _blockSizeVertical = 0;
int _blockSizeHorizontal = 0;
List _cells = [];
List _cellsSolved = [];
List _shuffledCellValues = [];
int _currentCellCol = null;
int _currentCellRow = null;
int _currentCellValue = null;
int? _currentCellCol;
int? _currentCellRow;
int? _currentCellValue;
bool _showConflicts = false;
int _givenTipsCount = 0;
String get level => _level;
void updateLevel(String level) {
_level = level;
void updateParameterLevel(String parameterLevel) {
_parameterLevel = parameterLevel;
notifyListeners();
}
String get size => _size;
int get blockSizeVertical => _blockSizeVertical;
int get blockSizeHorizontal => _blockSizeHorizontal;
void updateSize(String size) {
_size = size;
_blockSizeHorizontal = int.parse(_size.split('x')[0]);
_blockSizeVertical = int.parse(_size.split('x')[1]);
void updateParameterSize(String parameterSize) {
_parameterSize = parameterSize;
_blockSizeHorizontal = int.parse(_parameterSize.split('x')[0]);
_blockSizeVertical = int.parse(_parameterSize.split('x')[1]);
notifyListeners();
}
String get skin => _skin;
void updateSkin(String skin) {
_skin = skin;
void updateParameterSkin(String parameterSkin) {
_parameterSkin = parameterSkin;
notifyListeners();
}
getParameterValue(String parameterCode) {
switch(parameterCode) {
case 'difficulty': { return _level; }
break;
case 'size': { return _size; }
break;
case 'skin': { return _skin; }
break;
String getParameterValue(String parameterCode) {
switch (parameterCode) {
case 'level':
return _parameterLevel;
case 'size':
return _parameterSize;
case 'skin':
return _parameterSkin;
}
return '';
}
List getParameterAvailableValues(String parameterCode) {
switch(parameterCode) {
case 'difficulty': { return _availableDifficultyLevels; }
break;
case 'size': { return _availableSizes; }
break;
case 'skin': { return _availableSkins; }
break;
switch (parameterCode) {
case 'level':
return _availableLevelValues;
case 'size':
return _availableSizeValues;
case 'skin':
return _availableSkinValues;
}
}
setParameterValue(String parameterCode, String parameterValue) async {
switch(parameterCode) {
case 'difficulty': { updateLevel(parameterValue); }
break;
case 'size': { updateSize(parameterValue); }
break;
case 'skin': { updateSkin(parameterValue); }
break;
return [];
}
void setParameterValue(String parameterCode, String parameterValue) async {
switch (parameterCode) {
case 'level':
updateParameterLevel(parameterValue);
break;
case 'size':
updateParameterSize(parameterValue);
break;
case 'skin':
updateParameterSkin(parameterValue);
break;
}
final prefs = await SharedPreferences.getInstance();
prefs.setString(parameterCode, parameterValue);
......@@ -95,9 +104,9 @@ class Data extends ChangeNotifier {
void initParametersValues() async {
final prefs = await SharedPreferences.getInstance();
setParameterValue('difficulty', prefs.getString('difficulty') ?? _levelDefault);
setParameterValue('size', prefs.getString('size') ?? _sizeDefault);
setParameterValue('skin', prefs.getString('skin') ?? _skinDefault);
setParameterValue('level', prefs.getString('level') ?? _parameterLevelDefault);
setParameterValue('size', prefs.getString('size') ?? _parameterSizeDefault);
setParameterValue('skin', prefs.getString('skin') ?? _parameterSkinDefault);
}
bool get gameIsRunning => _gameIsRunning;
......@@ -126,31 +135,32 @@ class Data extends ChangeNotifier {
int maxCellValue = 16;
List values = new List<int>.generate(maxCellValue, (i) => i + 1);
if (_shufflableSkins.contains(_skin)) {
if (_shufflableSkins.contains(_parameterSkin)) {
values.shuffle();
print('Shuffled tiles values: ' + values.toString());
}
_shuffledCellValues = values;
}
int getTranslatedValueForDisplay(int originalValue) {
return _shuffledCellValues[originalValue - 1];
}
int get currentCellCol => _currentCellCol;
set updateCurrentCellCol(int currentCellCol) {
int? get currentCellCol => _currentCellCol;
set updateCurrentCellCol(int? currentCellCol) {
_currentCellCol = currentCellCol;
notifyListeners();
}
int get currentCellRow => _currentCellRow;
set updateCurrentCellRow(int currentCellRow) {
int? get currentCellRow => _currentCellRow;
set updateCurrentCellRow(int? currentCellRow) {
_currentCellRow = currentCellRow;
notifyListeners();
}
int get currentCellValue => _currentCellValue;
set updateCurrentCellValue(int currentCellValue) {
int? get currentCellValue => _currentCellValue;
set updateCurrentCellValue(int? currentCellValue) {
_currentCellValue = currentCellValue;
notifyListeners();
}
......@@ -160,12 +170,13 @@ class Data extends ChangeNotifier {
_givenTipsCount = _givenTipsCount + 1;
notifyListeners();
}
resetGivenTipsCount() {
_givenTipsCount = 0;
notifyListeners();
}
selectCell(int col, int row) {
selectCell(int? col, int? row) {
_currentCellCol = col;
_currentCellRow = row;
_currentCellValue = null;
......@@ -177,11 +188,13 @@ class Data extends ChangeNotifier {
notifyListeners();
}
updateCellValue(int col, int row, int value) {
if (!_cells[row][col].isFixed) {
_cells[row][col].value = value;
updateCellValue(int? col, int? row, int value) {
if ((col != null) && (row != null)) {
if (!_cells[row][col].isFixed) {
_cells[row][col].value = value;
}
notifyListeners();
}
notifyListeners();
}
bool get showConflicts => _showConflicts;
......@@ -189,6 +202,7 @@ class Data extends ChangeNotifier {
_showConflicts = showConflicts;
notifyListeners();
}
void toggleShowConflicts() {
updateShowConflicts(!showConflicts);
}
......@@ -208,6 +222,7 @@ class Data extends ChangeNotifier {
}
notifyListeners();
}
void resetAnimatedBackground() {
int boardSideLength = _blockSizeHorizontal * _blockSizeVertical;
for (var row = 0; row < boardSideLength; row++) {
......
......@@ -33,30 +33,21 @@ class _HomeState extends State<Home> {
'button_show_conflicts',
'button_start',
'game_win',
'placeholder',
'cell_empty'
];
myProvider.availableDifficultyLevels.forEach(
(difficulty) => gameImages.add('difficulty_' + difficulty)
);
myProvider.availableSizes.forEach(
(size) => gameImages.add('size_' + size)
);
myProvider.availableLevelValues.forEach((level) => gameImages.add('level_' + level));
myProvider.availableSizeValues.forEach((size) => gameImages.add('size_' + size));
gameImages.forEach(
(image) => assets.add('assets/icons/' + image + '.png')
);
gameImages.forEach((image) => assets.add('assets/icons/' + image + '.png'));
List skinImages = [];
for (int value = 1; value <= 16; value++) {
skinImages.add(value.toString());
}
myProvider.availableSkins.forEach(
(skin) => skinImages.forEach(
(image) => assets.add('assets/skins/' + skin + '_' + image + '.png')
)
);
assets.add('assets/skins/empty.png');
myProvider.availableSkinValues.forEach((skin) => skinImages
.forEach((image) => assets.add('assets/skins/' + skin + '_' + image + '.png')));
return assets;
}
......@@ -67,9 +58,7 @@ class _HomeState extends State<Home> {
if (!myProvider.assetsPreloaded) {
List assets = getImagesAssets(myProvider);
assets.forEach(
(asset) => precacheImage(AssetImage(asset), context)
);
assets.forEach((asset) => precacheImage(AssetImage(asset), context));
myProvider.updateAssetsPreloaded(true);
}
......@@ -77,7 +66,7 @@ class _HomeState extends State<Home> {
if (myProvider.gameIsRunning) {
menuActions = [
FlatButton(
TextButton(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
......@@ -86,17 +75,16 @@ class _HomeState extends State<Home> {
width: 4,
),
),
margin: EdgeInsets.all(8),
child: Image(
image: AssetImage('assets/icons/button_back.png'),
fit: BoxFit.fill
fit: BoxFit.fill,
),
),
onPressed: () => toast('Long press to quit game...'),
onLongPress: () => GameUtils.resetGame(myProvider),
),
Spacer(flex: 6),
FlatButton(
TextButton(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
......@@ -105,31 +93,27 @@ class _HomeState extends State<Home> {
width: 4,
),
),
margin: EdgeInsets.all(8),
child: Badge(
showBadge: myProvider.givenTipsCount == 0 ? false : true,
badgeColor:
myProvider.givenTipsCount < 10
badgeColor: myProvider.givenTipsCount < 10
? Colors.green
: myProvider.givenTipsCount < 20
? Colors.orange
: Colors.red,
? Colors.orange
: Colors.red,
badgeContent: Text(
myProvider.givenTipsCount == 0 ? '' : myProvider.givenTipsCount.toString(),
style: TextStyle(
color: Colors.white
)
style: TextStyle(color: Colors.white),
),
child: Image(
image: AssetImage('assets/icons/button_help.png'),
fit: BoxFit.fill
fit: BoxFit.fill,
),
)
),
),
onPressed: () => GameUtils.showTip(myProvider),
),
Spacer(),
FlatButton(
TextButton(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
......@@ -138,10 +122,9 @@ class _HomeState extends State<Home> {
width: 4,
),
),
margin: EdgeInsets.all(8),
child: Image(
image: AssetImage('assets/icons/button_show_conflicts.png'),
fit: BoxFit.fill
fit: BoxFit.fill,
),
),
onPressed: () {
......@@ -158,10 +141,10 @@ class _HomeState extends State<Home> {
body: SafeArea(
child: Center(
child: myProvider.gameIsRunning
? Game.buildGameWidget(myProvider)
: Parameters.buildParametersSelector(myProvider)
? Game.buildGameWidget(myProvider)
: Parameters.buildParametersSelector(myProvider),
),
)
),
);
}
}