Triple check that, will ya?

device-2017-03-08-124806A long long time ago
I can still remember how
That App used to make me smile….
And I knew if I had my chance
That I could make those dice dance
And maybe they’d be happy for a while….

Uh, wrong lyrics. Actually, it was quite a while ago that I made the Android app, Ships, Captain, and Crew! After the move from GitHub to GitLab, I decided to look over some of my old issues that were imported with GitLab’s great import tool. Among them, I found two issues for this old app that I had made.

The first was that of an issue with screen rotation causing the app to restart. I quickly fixed that by just setting the activity to portrait mode in the manifest file. You can check my commit if you need details.

The second issue was a bit more complicated, in that there was a problem with checking the dice for a ship, captain, or crew. Essentially, if you rolled a 4, 5, 6, 1, and 3, it would say you only have a ship (the 6) and no captain (5) or crew (4). Obviously that’s wrong. The issue is that you need a 6 before you can keep a 5 or 4. And since the dice were checked in order, when it looked at the 5 or 4, it did not have a 6 yet, so they were not “kept”.

This is how I fixed it:

for (int i = 0; i < 3; i++) {

// Check three times.

myNumber = firstDie;

diceCheck();

if (waschecked){

firstnotchecked = false;

}

dieOne.setImageResource(id);

myNumber = secondDie;

diceCheck();

if (waschecked){

secondnotchecked = false;

}

dieTwo.setImageResource(id);

myNumber = thirdDie;

diceCheck();

if (waschecked){

thirdnotchecked = false;

}

dieThree.setImageResource(id);

myNumber = fourthDie;

diceCheck();

if (waschecked){

fourthnotchecked = false;

}

dieFour.setImageResource(id);

myNumber = fifthDie;

diceCheck();

if (waschecked){

fifthnotchecked = false;

}


dieFive.setImageResource(id);


}

As you can see,  I told it to check the dice, first to last, three times. Yes, this is ugly and poor programming. Actually, I was almost ashamed of this early work, it looked so congested and terrible. However, my goal today was the quick fix, so that’s what I did. Hopefully, the update will be available on F-Droid soon, so you’ll have to check it out!

Linux – keep it simple.

Advertisements

Game restarts when minimized!

When I originally created JustChess, I had a problem. If you were playing a game, and pressed the new game button, then started another game, you could press back and go back to the menu, then back and go back to the game. This was a bit odd. At the time, I solved it with “Intent.FLAG_ACTIVITY_NO_HISTORY”. This worked great. Too great.

The problem, as pointed out on my issue tracker, was that when you minimized the game, it would be “destroyed” and rebuilt when you brought the app back. Which is not cool. You may need to answer a text and then come back to your game, and it shouldn’t disappear in between!

minimized

So, I fixed it with my latest commit. I took out the FLAG_ACTIVITY_NO_HISTORY intents, but then my original problem returned. To solve that, I added “finish()” to my new game button, like so:

// First you define it.
Intent myintent = new Intent(MainActivity.this, IntroActivity.class);
// Now you call it.
startActivity(myintent);
finish();

}
})

Now, when you select a new game, it “finishes” your old one. Pressing the back button doesn’t lead you on a wild goose chase to dozens of old games, it just brings you back to the main menu, and that’s much better!

Linux – keep it simple.

JelloStorm.cpp:198:58: error: ?createBackground? was not declared in this scope

grass

After the rough time I had completing section 6 of the course, I was not looking forward to section 7. However, it turned out that section 6 was just tough, and section 7 was pretty easy. That doesn’t mean I didn’t have any trouble though.

alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~/Documents/c++/Cpp_training/JelloStorm$ ./build.sh
JelloStorm.cpp: In function ?int main()?:
JelloStorm.cpp:198:58: error: ?createBackground? was not declared in this scope
int tileSize = createBackground(tileBackground, arena);
^

Turns out when you make a header file, you have to be sure to include it! Yes, I forgot that line, so I fixed it as such:

#include <SFML/Graphics.hpp>
#include <sstream>
#include <SFML/Audio.hpp>
#include <Player.h>
#include <JelloStorm.h>

And now that it is fixed, my archer has a nice grassy field to walk around in! You can check out the game thus far or the commit at my GitLab!

Linux – keep it simple.

Can’t play chess in landscape mode!

Another one of the great issues brought up by a user of JustChess, my simple chess playing Android app, was the fact that when the screen was rotated, you can’t see the bottom half of the board!

Realistically, this would require one of two things:

  1. Fixed portrait mode, not allowing the user to rotate the screen.
  2. Having a separate layout that was appropriate for the rotated screen.

But instead I chose option number 3: Add a scroll view!

Option 1 would limit users from being able to hold their phone a different way if it was more comfortable, and that doesn’t solve any problems, it just limits use.

Option 2 is the proper way to fix this, but I’m done working on this app right now, and involved in other project. This would be a bit of an overhaul, and would take me a considerable amount of time.

Option 3, is cheating. I am adding a scroll view so that the user who wants to play in landscape view can scroll the board to recenter it on the screen. This is fine for hi-res screens we see today, but may be a problem on an older phone, where the user would have to scroll the board back and forth to see all of it.

slide

Either way, you can see the full commit on my GitLab, but here is the pertinent part of the code, in the layout xml file:

<ScrollView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <LinearLayout
...... edited for space .......
    </LinearLayout>
</ScrollView>

This neatly wraps everything up into a nested scroll view which the user can move by swiping. This may also help if in portrait mode on an older phone with a very small screen.

Linux – keep it simple.

The game restarts on screen rotation!

After my JustChess app hit the F-Droid repository, I was pleasantly surprised to hear that people were trying it out! With every wave of players, however, came a new wave of issues. I like issues. I’m a bit of a problem solver, so it gives me a clear direction to work towards.

One of the issues was that rotating the screen caused the current game to be destroyed and restarted. Of course! I should have thought about that. Since I sold my Android phones, I was using the emulator to finish building this game. With the emulator, I didn’t consider screen rotation!

Fortunately, the first fix is pretty simple. If your activity restarts on rotation, then you should add this line to your manifest for each activity:

android:configChanges="orientation|screenSize"

Like this:

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.NoActionBar" />

You can check out the full commit on my GitLab, but that is all you need to fix this issue. Now I just need to make it playable when the screen is rotated!

rotating

Linux – keep it simple.

Cancel all notifications!

While trying to update and add features to my old open source Hourglass app, I decided that the issue posted asking for a notification cancel button was a pretty good idea!

Screenshot from 2018-05-02 13-12-03

Now you can cancel your timer at any time from the notification bar! The code was pretty simple, actually, and you can read the entire commit on my GitLab, but here is the important part:

// as a result of notification action
Intent detailsIntent = new Intent(MainActivity.this, CancelActivity.class);
detailsIntent.putExtra("EXTRA_DETAILS_ID", 42);
PendingIntent detailsPendingIntent = PendingIntent.getActivity(
      MainActivity.this,
      0,
      detailsIntent,
      PendingIntent.FLAG_UPDATE_CURRENT
      );

NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
        .setSmallIcon(R.drawable.hourglass).setWhen(System.currentTimeMillis()+recureTime).setUsesChronometer(true)
        .setContentTitle("Hourglass").setContentText(intentPhrase).addAction(
                android.R.drawable.ic_notification_clear_all, "Cancel", detailsPendingIntent);

Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0 , intent, PendingIntent.FLAG_UPDATE_CURRENT);

This mumbo jumbo just allows the cancel button to be displayed, which, if pressed, calls the CancelActivity class.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set the screen orientation to portrait to keep the screen rotation bug from stoping
    // the timer on some phones.
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    // Just log.
    Log.i("WJH", "CancellAll.");
    allCancel = true;
    finish();

}

The moment the CancelActivity.java class opens, it set’s the boolean allCancel to true (meaning yes, we want to cancel) and exits back to the MainActivity class, where the timer is running.

Then, on every tick of the timer, it checks to see if allCancel is true or false. If true, it cancels the timer, repeating timer, and recurring alarm. If false, it continues to count down as usual. Praise God! It actually works! Be sure to check out revision 1.9 of the app for this latest feature! And thanks to “brunetton” for the great idea!

Linux – keep it simple.

Can you say that again, Mr. Alarm?

While using my Hourglass app for Android phones, a user made an interesting observation:

Hi
I love this open source app and using it quite often. But sometimes my phone is in my pocket and I’m listening to music and I miss the time ended notification ! The vibration is short, easy to miss, same thing for the notifications sounds. I’d find “logical” to have a continuous notification that vibrates and rings until I manually stop it (from notification bar or inside app).
Is this feature planned for a future release ?
Thanks

What a great idea! I’m glad that “bruneton” opened this issue on my issue tracker. That’s part of the beauty of open source. Sure, closed source programs could take input as well, but the open source community encourages and enables it, as well as giving others the code so that they can make changes themselves!

So, I added another button:

time_up

And with that button, some new code, which you can check out in full from the commit on my GitLab, but here is the gist of it:

– // Cancel the notification.
 – mNotificationManager.cancel(0);

 – // Set the time bar back to usable.
 – timeBar.setEnabled(true);
 + if (alreYes) {
 +
 + startCount(2000,1000);
 +
 + } else {
 + // Cancel the notification.
 + mNotificationManager.cancel(0);
 +
 + // Set the time bar back to usable.
 + timeBar.setEnabled(true);
 + }

What we have here, is a repeating timer that, if the continuous alarm is set, will “repeat” by resetting the countdown to 2 seconds, over and over again, until you cancel the repeating alarm!

It seems to work well so far, but I think I can do better. So, I’m looking at adding a “Stop” or “Cancel” option to the notification pop up. We’ll see, but for now, it does repeat rather nicely!

Linux – keep it simple.

Adding a countdown timer to my Android notification….

This was actually a great idea brought up by a user, and posted in my issue tracker for the Hourglass app. He pointed out that it would be really handy to have the remaining time posted in the notification popup, and get it to be consistently updated.

I thought there must surely be something for this in Android already, but I couldn’t find one. However, I did find a chronometer that can count how long a notification has been open. With some careful thought, here is what I came up with:

NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
        .setSmallIcon(R.drawable.hourglass).setWhen(System.currentTimeMillis()+recureTime).setUsesChronometer(true)
        .setContentTitle("Hourglass").setContentText(intentPhrase);

What I found was that I could “back up” time to before the notification started. Essentially giving it a negative number. Then, passing the time saved for recurring alarms (even saved if not used), then I can set it to a negative of that number. Now it counts “up” from negative time, giving the appearance of counting down your timer!

timer_notification

Works pretty well, however, 2 interesting things. I would have thought the code should be MINUS recureTime, not PLUS recureTime, but it only works properly with PLUS.

Second, the “countdown timer” in the notification doesn’t track exactly with the Hourglass app timer. In the course of several minutes, it becomes off by a second. Odd, but workable. The timer still goes off in the app on time, just that the countdown in the notification may get there a second early.

Linux – keep it simple.

Fool’s Mate Friday: Where to, Governor?

Today’s update is pretty basic. Just cleaning up and filling in some blanks on my JustChess app. While I wont bore you with the whole commit, you are welcome to check it out.

jc9

Basically, I just added an about and settings page. Both pages are pretty basic, but the settings page does have a cool star strength indicator for the computer engine strength. I thought it wise to add it so people could play against the JustChessEngine at lower strengths. It seems a bit funny, since it is currently so weak that I doubt this would be needed. However, it seemed to me, that when making a full fledged app of this sort, one would include some sort of slider or adjustment for the engine strength, so there it is.

This does beg the question of where to go next. As is, my goal was to learn more app making skills and increase my java strength by creating a chess app in which I made my own engine, and one that you could play against a person or a computer. To God be the glory, this app has met that goal. With pass’n’play mode, you could play a friend in a room, or with single player, you can play as black or white against your phone.

But the road forks here.

On the one hand, I could pursue the avenue of making the game playable with someone who was not in the same room, via email, text, online server (parse comes to mind, as I set one of those up for a different app). On the other hand, I could focus on the engine and try to make it stronger.

And yet the road forks again….

One of the big problems is that of programming language. As I delve deeper and deeper into java, I have found only one place that it is applicable, Android. As I’m sure you have seen from my blog, I’ve switched to using Ubuntu Touch on my phone. But Ubuntu Touch doesn’t support java naively (or perhaps at all). As I continue to apply time to learning java, I continue to limit myself to just one application. Perhaps it would be better to learn c++, java-script, or some other language that has a broader application?

So, I sit at the cross roads. What to do next? Hopefully I can figure it out before the next Fool’s Mate Friday!

Linux – keep it simple.

Fool’s Mate Friday: Check or Stale Mate?

Apparently, in 1988, World Champion Gary Kasparov accidentally stalemated his opponent during a blitz tournament in Canada. Mr. Kasparov had a king, queen, and a bishop against Kiril Dimitrov Georgiev’s lone king. The problem Mr. Kasparov was facing was that of time running out. In his efforts to move quicker, he forced a stalemate when he had every advantage and reason to win!

I will probably never be as great as Mr. Kasparov, so I certainly mean no disrespect when bringing this up. My point being is that even world champions can stalemate. How does this apply to my JustChess app? Well, it seems to me that it is pretty important to clarify when the opponent can’t move, if they are in stalemate, or checkmate.

Fortunately, I figured out how to do just that.

jc8

The code wasn’t particularly grueling, it turned out the hard part was figuring out the order of play for pass and play verses playing against the computer. The time which you need to look for a checkmate or stalemate actually changes between those two. Here’s the important snippet, but as always, you can check it out on my GitHub.

    moveOptions="";
    if (!wTurn){
        moveOptions= terminal("suggestMove,black");
    } else {
        moveOptions= terminal("suggestMove,white");
    }
    if (moveOptions.isEmpty()) {
        staleOrCheckMate();
    }

} // End clicked piece.

public void staleOrCheckMate() {
    String status = terminal("checkmate");
    if (status.equalsIgnoreCase("1")) {
        status = "checkmate!";
    } else {
        status = "stalemate!";
    }
    String turnIs = "";
    if (wTurn) {turnIs="White is in ";} else {turnIs="Black is in ";}
    new AlertDialog.Builder(this)
            .setIcon(android.R.drawable.ic_dialog_info)
            .setTitle(turnIs + status)
            .setMessage(
                    "Would you like to play a new game?")
            .setPositiveButton("View Board", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {

                    // Do nothing.

                }
            })
            .setNegativeButton("New Game", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {

                    // First you define it.
                    Intent myintent = new Intent(MainActivity.this, IntroActivity.class);
                    myintent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                    // Now you call it.
                    startActivity(myintent);

                }
            })
            .show(); // Make sure you show your popup or it wont work very well!

}

The longest part of this project was actually testing it against the computer! It’s easy to checkmate it right now, but I found it was a pesky bugger to stalemate! Be sure to give it a try, my GitHub has all of the updates of the app already built for you to download and test out!

Linux – keep it simple.