diff --git a/assets/time.svg b/assets/time.svg new file mode 100644 index 0000000..69994af --- /dev/null +++ b/assets/time.svg @@ -0,0 +1,59 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/po/fr.po b/po/fr.po index 7f35e03..03953b8 100644 --- a/po/fr.po +++ b/po/fr.po @@ -79,13 +79,15 @@ msgstr "Nouvelle partie" #: ../qml/Main.qml:242 msgid "Version: " -msgstr "" +msgstr "Version : " #. TRANSLATORS: Short description #: ../qml/Main.qml:251 msgid "" "Mines is a puzzle game where the goal is to find the mines in a minefield." msgstr "" +"Démineur est un jeu de réflexion dont le but est de localiser les mines dans" +"un champ de mines." #. TRANSLATORS: Game instructions #: ../qml/Main.qml:261 @@ -96,6 +98,12 @@ msgid "" "a mine to check next. If you hit a mine it explodes and the game is over. " "You can flag where a mine is by touching and holding that square. Have fun!" msgstr "" +"Le champ de mines est représenté par une grille. Touchez une case pour " +"vérifier si elle cache une mine. S'il n'y a pas de mine, la case dévoilera le " +"nombre de mines autour de la case. Déduisez-en une case qui ne peut pas " +"contenir de mine et dévoilez-la. Si vous touchez une mine, celle-ci explose " +"et la partie est terminée. Vous pouvez marquer une case avec un drapeau en la " +"maintenant appuyée pour indiquer qu'elle contient une mine. Amusez-vous!" #. TRANSLATORS: GPL notice #: ../qml/Main.qml:271 @@ -109,26 +117,34 @@ msgid "" "href='https://www.gnu.org/licenses/gpl-3.0.en.html'>GNU General Public " "License for more details." msgstr "" +"Ce programme est un logiciel libre : vous pouvez le partager et/ou le modifier" +" en respectant les termes de la licence GNU General Public License telle que " +"publiée par la Free Software Foundation, dans sa 3e version ou (au choix) dans" +" une version postérieure. Ce programme est partagé dans l'espoir qu'il soit " +"utile, mais SANS AUCUNE GARANTIE; sans même une garantie de MARCHANDISATION " +"ni de COMPATIBILITÉ POUR UN USAGE SPÉCIFIQUE. Consultez la GNU General Public " +"License pour plus de détails." #: ../qml/Main.qml:280 msgid "SOURCE" -msgstr "" +msgstr "SOURCE" #: ../qml/Main.qml:280 msgid "ISSUES" -msgstr "" +msgstr "BOGUE" #: ../qml/Main.qml:280 msgid "DONATE" -msgstr "" +msgstr "FAIRE UN DON" #: ../qml/Main.qml:290 msgid "Copyright (c) 2015 Robert Ancell" -msgstr "" +msgstr "Copyright (c) 2015 Robert Ancell" #: ../qml/Main.qml:299 msgid "Copyright (c) 2017 Jan Sprinz " -msgstr "" +msgstr "Copyright (c) 2017 Jan Sprinz " #. TRANSLATORS: Title of page showing high scores #: ../qml/Main.qml:309 diff --git a/po/mines.neothethird.pot b/po/mines.neothethird.pot index b17395f..d1b4db8 100644 --- a/po/mines.neothethird.pot +++ b/po/mines.neothethird.pot @@ -1,6 +1,6 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. +# This file is distributed under the same license as the mines.neothethird package. # FIRST AUTHOR , YEAR. # #, fuzzy @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: mines.neothethird\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-09-23 19:47+0000\n" +"POT-Creation-Date: 2018-10-24 01:26+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,76 +18,76 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #. TRANSLATORS: Title for dialog shown when starting a new game while one in progress -#: ../qml/Main.qml:92 +#: ../qml/Main.qml:98 msgid "Game in progress" msgstr "" #. TRANSLATORS: Content for dialog shown when starting a new game while one in progress -#: ../qml/Main.qml:94 +#: ../qml/Main.qml:100 msgid "Are you sure you want to restart this game?" msgstr "" #. TRANSLATORS: Button in new game dialog that cancels the current game and starts a new one -#: ../qml/Main.qml:97 +#: ../qml/Main.qml:103 msgid "Restart game" msgstr "" #. TRANSLATORS: Button in new game dialog that cancels new game request -#: ../qml/Main.qml:106 +#: ../qml/Main.qml:112 msgid "Continue current game" msgstr "" #. TRANSLATORS: Title for dialog confirming if scores should be cleared #. TRANSLATORS: Button in clear scores dialog that clears scores #. TRANSLATORS: Action in high scores page that clears scores -#: ../qml/Main.qml:117 ../qml/Main.qml:122 ../qml/Main.qml:324 +#: ../qml/Main.qml:123 ../qml/Main.qml:128 ../qml/Main.qml:425 msgid "Clear scores" msgstr "" #. TRANSLATORS: Content for dialog confirming if scores should be cleared -#: ../qml/Main.qml:119 +#: ../qml/Main.qml:125 msgid "Existing scores will be deleted. This cannot be undone." msgstr "" #. TRANSLATORS: Button in clear scores dialog that cancels clear scores request -#: ../qml/Main.qml:131 +#: ../qml/Main.qml:137 msgid "Keep existing scores" msgstr "" #. TRANSLATORS: Title of application -#: ../qml/Main.qml:147 ../qml/Main.qml:234 +#: ../qml/Main.qml:153 ../qml/Main.qml:335 msgid "Mines" msgstr "" #. TRANSLATORS: Action on main page that shows game instructions #. TRANSLATORS: Title of page with game instructions -#: ../qml/Main.qml:151 ../qml/Main.qml:208 +#: ../qml/Main.qml:157 ../qml/Main.qml:309 msgid "How to Play" msgstr "" #. TRANSLATORS: Action on main page that shows settings dialog #. TRANSLATORS: Title of page showing settings -#: ../qml/Main.qml:157 ../qml/Main.qml:337 +#: ../qml/Main.qml:163 ../qml/Main.qml:438 msgid "Settings" msgstr "" #. TRANSLATORS: Action on main page that starts a new game -#: ../qml/Main.qml:163 +#: ../qml/Main.qml:169 msgid "New Game" msgstr "" -#: ../qml/Main.qml:252 +#: ../qml/Main.qml:353 msgid "Version: " msgstr "" #. TRANSLATORS: Short description -#: ../qml/Main.qml:261 +#: ../qml/Main.qml:362 msgid "" "Mines is a puzzle game where the goal is to find the mines in a minefield." msgstr "" #. TRANSLATORS: Game instructions -#: ../qml/Main.qml:271 +#: ../qml/Main.qml:372 msgid "" "The minefield is divided into a grid of squares. Touch a square to check if " "there is a mine there. If no mine is present the square will show the number " @@ -97,7 +97,7 @@ msgid "" msgstr "" #. TRANSLATORS: GPL notice -#: ../qml/Main.qml:281 +#: ../qml/Main.qml:382 msgid "" "This program is free software: you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " @@ -109,52 +109,52 @@ msgid "" "License for more details." msgstr "" -#: ../qml/Main.qml:290 +#: ../qml/Main.qml:391 msgid "SOURCE" msgstr "" -#: ../qml/Main.qml:290 +#: ../qml/Main.qml:391 msgid "ISSUES" msgstr "" -#: ../qml/Main.qml:290 +#: ../qml/Main.qml:391 msgid "DONATE" msgstr "" -#: ../qml/Main.qml:300 +#: ../qml/Main.qml:401 msgid "Copyright (c) 2015 Robert Ancell" msgstr "" -#: ../qml/Main.qml:309 +#: ../qml/Main.qml:410 msgid "Copyright (c) 2017 Jan Sprinz " msgstr "" #. TRANSLATORS: Title of page showing high scores -#: ../qml/Main.qml:321 +#: ../qml/Main.qml:422 msgid "High Scores" msgstr "" #. TRANSLATORS: Label beside checkbox setting for controlling vibrations when placing flags -#: ../qml/Main.qml:349 +#: ../qml/Main.qml:450 msgid "Vibrate when placing flags" msgstr "" #. TRANSLATORS: Label above setting to choose the minefield size -#: ../qml/Main.qml:359 +#: ../qml/Main.qml:460 msgid "Minefield size:" msgstr "" #. TRANSLATORS: Setting name for small minefield -#: ../qml/Main.qml:366 +#: ../qml/Main.qml:467 msgid "Small" msgstr "" #. TRANSLATORS: Setting name for large minefield -#: ../qml/Main.qml:369 +#: ../qml/Main.qml:470 msgid "Large" msgstr "" #. TRANSLATORS: Description format for minefield size, %width%, %height% and %nmines% is replaced with the field width, height and number of mines -#: ../qml/Main.qml:375 +#: ../qml/Main.qml:476 msgid "%width%×%height%, %nmines% mines" msgstr "" diff --git a/qml/Main.qml b/qml/Main.qml index a752179..f126e06 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -82,6 +82,12 @@ MainView { { var grid_options = size_selector.model.get(size_selector.selectedIndex) minefield.set_size(grid_options.grid_width, grid_options.grid_height, grid_options.n_mines) + reset_timer() + } + + function reset_timer() + { + if (!minefield.completed && !timer.running) { timer.start() } } Component { @@ -175,11 +181,14 @@ MainView { MinefieldModel { id: minefield onSolved: { - get_history_database().transaction(function(t) { - t.executeSql("CREATE TABLE IF NOT EXISTS History(grid_width INTEGER, grid_height INTEGER, n_mines INTEGER, date TEXT, duration INTEGER)") - var duration = minefield.end_time - minefield.start_time - t.executeSql("INSERT INTO History VALUES(?, ?, ?, ?, ?)", [minefield.columns, minefield.rows, minefield.n_mines, minefield.start_time.toISOString(), duration]) - }) + if (minefield.loosed != true) { + get_history_database().transaction(function(t) { + t.executeSql("CREATE TABLE IF NOT EXISTS History(grid_width INTEGER, grid_height INTEGER, n_mines INTEGER, date TEXT, duration INTEGER)") + var duration = minefield.end_time - minefield.start_time + t.executeSql("INSERT INTO History VALUES(?, ?, ?, ?, ?)", [minefield.columns, minefield.rows, minefield.n_mines, minefield.start_time.toISOString(), duration]) + }) + } + timer.stop() } } @@ -187,7 +196,7 @@ MainView { width: parent.width anchors { top: main_header.bottom - bottom: parent.bottom + bottom: statBar.top } anchors.margins: units.gu(2) MinefieldView { @@ -197,6 +206,98 @@ MainView { use_haptic_feedback: haptic_check.checked } } + + Rectangle { + id: statBar + width: parent.width + height: units.gu(20) + anchors.bottom: parent.bottom + + Rectangle { + height: parent.height + width: parent.width/2 + anchors { + left: parent.left + } + + Row { + height: parent.height + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + + Image { + id: time_icon + anchors { + verticalCenter: parent.verticalCenter + margins: units.gu(2) + } + source: "../assets/time.svg" + } + Rectangle{ + width: units.gu(8) + height: parent.height + anchors.verticalCenter: parent.verticalCenter + + Item { + Component.onCompleted: reset_timer() + Timer { + id: timer + interval: 500; running: false; repeat: true + onTriggered: time.text = minefield.update_time_elapsed() + } + } + Text { + id: time + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + } + } + } + } + + Rectangle { + height: parent.height + width: parent.width/2 + anchors { + right: parent.right + } + + Row { + height: parent.height + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + + Image { + id: mine_icon + anchors { + verticalCenter: parent.verticalCenter + margins: units.gu(2) + } + source: "../assets/mine.svg" + } + + Rectangle{ + width: units.gu(8) + height: parent.height + anchors.verticalCenter: parent.verticalCenter + + Text { + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + text: minefield.n_flags + "/" + minefield.n_mines + } + } + } + } + } } Page { @@ -396,6 +497,12 @@ MainView { grid_height: 16 n_mines: 25 } + // ListElement { + // name: "test" + // grid_width: 3 + // grid_height: 3 + // n_mines: 2 + // } } } } diff --git a/qml/MinefieldModel.qml b/qml/MinefieldModel.qml index 8502b01..dd0d7a8 100644 --- a/qml/MinefieldModel.qml +++ b/qml/MinefieldModel.qml @@ -33,9 +33,12 @@ ListModel { property bool started: false property int n_checked: 0 property int n_mines + property int n_flags: 0 property bool completed: false + property bool loosed: false property var start_time property var end_time + property double time_elapsed signal solved() function set_size(n_columns, n_rows, n) { @@ -44,7 +47,9 @@ ListModel { started = false n_checked = 0 n_mines = n + n_flags = 0 completed = false + loosed = false clear() for(var row = 0; row < n_rows; row++) { for(var column = 0; column < n_columns; column++) { @@ -71,6 +76,9 @@ ListModel { // Can only flag unknown cells if(cell.checked) { return false } + // Update n_flags + if(cell.flagged) { n_flags-- } + else { n_flags++ } // toggle flag status cell.flagged = !cell.flagged @@ -109,6 +117,8 @@ ListModel { if(cell.has_mine) { completed = true + loosed = true + solved() } else { var n_flagged_mines = n_surrounding_flagged(cell.column, cell.row) if(cell.n_surrounding <= n_flagged_mines) { @@ -179,4 +189,16 @@ ListModel { } } } + + function update_time_elapsed() { + if (started) { + time_elapsed = new Date() - start_time + var minutes = Math.floor(time_elapsed / 60000) + var seconds = ((time_elapsed % 60000) / 1000).toFixed(0) + return (seconds == 60 ? (minutes+1) + ":00" : (minutes < 10 ? "0" : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds) + } + else { + return "00:00" + } + } }