Mostrar mensagens com a etiqueta Android. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Android. Mostrar todas as mensagens

domingo, agosto 25, 2019

Android App: Tic-Tac-Toe Game


(Cover page of JME's Nr. 194 edition; 2001-01-15)


Many eons ago (2001 to be precise) I published a paper on the JME (Jornal de Matemática Elementar) edited by SPM - Portuguese Mathematical Society (edited by Prof. Sérgio Macias Marques), regarding the Tic-Tac-Toe game.




At the time I implemented the code in VB with a Game Engine, i.e., game implemented in a Human vs. Computer fashion [(1) the code comments are in Portuguese and (2) it's not even indented; copy pasting ancient code is a bummer! I can't be arsed with doing them both...if you want, do it yourself you lazy sod!]:

VB Code:

Option Explicit

' Desenhar o quadrado.

Private Sub DrawSquare(i As Integer) Select Case Board(i)
Case PlayerX X1(i).Visible = True X2(i).Visible = True
Case PlayerO O(i).Visible = True

End Select End Sub

Inicializar as opções.

Private Sub Form_Load() CenterForm Me Initialize
End Sub

Verificar se alguém ganhou.

Private Function GameOver() As Integer Dim pl As Integer
Dim i As Integer Dim color As Long

pl = Winner()
If pl = PLAYER_NONE Then GameOver = False
Exit Function End If

GameInProgress = False If pl = PlayerX Then
Msg.Caption = "X ganhou." ElseIf pl = PlayerO Then
Msg.Caption = "O ganhou." Else
Msg.Caption = "Empate." End If
Beep

GameOver = True End Function

Inicializar as opções.

Private Sub Initialize()

Inicializar opções iniciais.

SkillLevel = 1 mnuOptionsLevel(SkillLevel).Checked = True

PlayerX = PLAYER_HUMAN PlayerO = PLAYER_COMPUTER
mnuOptionsPlayX.Checked = True

' Começar novo jogo.

StartNewGame End Sub

Fazer o movimento do computador.

Private Sub MakeComputerMove()
Dim Square As Integer

Preparação.

Msg.Caption = "É a vez do computador." Msg.Refresh
MousePointer = vbHourglass

Escolher uma jogada.

Square = PickComputerMove

Seleccionar uma célula.

Board(Square) = NextPlayer

' Actualizar o display.
DrawSquare Square

' Preparar-se para a próxima jogada. NextPlayer = PLAYER_HUMAN MousePointer = vbDefault
End Sub

Jogada do humano.

Private Sub MakeHumanMove() Msg.Caption = "É a sua vez."
End Sub

Private Sub mnuFileExit_Click() Unload Me
End Sub

Seleccionar o nível de dificuldade.

Private Sub mnuOptionsLevel_Click(Index As Integer) mnuOptionsLevel(SkillLevel).Checked = False SkillLevel = Index mnuOptionsLevel(SkillLevel).Checked = True StartNewGame
End Sub

O humano é O.

Private Sub mnuOptionsPlayO_Click() PlayerX = PLAYER_COMPUTER PlayerO = PLAYER_HUMAN mnuOptionsPlayX.Checked = False mnuOptionsPlayO.Checked = True StartNewGame
End Sub

O humano é X.

Private Sub mnuOptionsPlayX_Click() PlayerX = PLAYER_HUMAN PlayerO = PLAYER_COMPUTER
mnuOptionsPlayX.Checked = True mnuOptionsPlayO.Checked = False StartNewGame
End Sub

Preparar-se para receber a próxima jogada.

Private Sub PlayerHasMoved()

Se o computador precisar de jogar, faça-o.

If NextPlayer = PLAYER_COMPUTER Then MakeComputerMove
If GameOver() Then Exit Sub End If

Agora o humano deve jogar.

MakeHumanMove End Sub

O humano está a jogar.

Private Sub Square_Click(Index As Integer)

' Validar se existe um jogo a decorrer. If Not GameInProgress Then Exit Sub

Validar se é o humano a jogar.

If NextPlayer <> PLAYER_HUMAN Then Exit Sub

Validar que ninguém está a ocupar esta célula.

If Board(Index) <> PLAYER_NONE Then Exit Sub

Seleccionar a célula. Board(Index) = NextPlayer DrawSquare Index

If GameOver() Then Exit Sub

Preparar-se para a próxima jogada. NextPlayer = PLAYER_COMPUTER PlayerHasMoved
End Sub

Inicializar o tabuleiro.

Private Sub StartNewGame()
Dim i As Integer

Inicializar o tabuleiro.

For i = 1 To NUM_SQUARES Board(i) = PLAYER_NONE X1(i).Visible = False X2(i).Visible = False O(i).Visible = False
Next i
NextPlayer = PlayerX GameInProgress = True

Iniciar primeira jogada.

PlayerHasMoved End Sub

Retornar o jogador que ganhou. Private Function Winner() As Integer Dim i As Integer

Procurar vitórias nas linhas.

For i = 1 To 7 Step 3
If Board(i) <> PLAYER_NONE Then
If Board(i) = Board(i + 1) And Board(i) = Board(i + 2) Then Winner = Board(i)
Exit Function End If
End If Next i

Procurar vitórias nas colunas.

For i = 1 To 3
If Board(i) <> PLAYER_NONE Then
If Board(i) = Board(i + 3) And Board(i) = Board(i + 6) Then Winner = Board(i)
Exit Function End If

End If Next i

Procurar vitórias nas diagonais.

If Board(1) <> PLAYER_NONE Then
If Board(1) = Board(5) And Board(1) = Board(9) Then Winner = Board(1)
Exit Function End If
End If
If Board(3) <> PLAYER_NONE Then
If Board(3) = Board(5) And Board(3) = Board(7) Then Winner = Board(3)
Exit Function End If
End If

Não há vencedor. Validar se é um empate.

Winner = PLAYER_NONE ' partir do princípio que o jogo ainda não terminou.
For i = 1 To NUM_SQUARES
If Board(i) = PLAYER_NONE Then Exit Function Next i

' É um empate.
Winner = PLAYER_DRAW End Function

O código fonte do nosso “module” é : Option Explicit
Public Const NUM_SQUARES = 9
Public Board(1 To NUM_SQUARES) As Integer Public GameInProgress As Integer

Valores dos jogadores.

Public Const PLAYER_DRAW = -1 Public Const PLAYER_NONE = 0 Public Const PLAYER_HUMAN = 1 Public Const PLAYER_COMPUTER = 2 Public Const NUM_PLAYERS = 2

Public NextPlayer As Integer ' O jogador que se deve mover a seguir.
Public PlayerX As Integer ' Os jogadores que são X/O são
Public PlayerO As Integer ' PLAYER_HUMAN ou PLAYER_COMPUTER.

Public SkillLevel As Integer


Public Function PickComputerMove() Dim pick As Integer

Select Case SkillLevel

Case 1 ' Nível de dificuldade 1

O computador limita-se a efectuar um ' movimento aleatório.


PickComputerMove = MakeRandomMove Exit Function


Case 2 ' Nível de dificuldade 2
pick = MakeWinningMove If pick = 0 Then
pick = MakeSavingMove
Else
PickComputerMove = pick Exit Function
End If

If pick = 0 Then
PickComputerMove = MakeRandomMove Else
PickComputerMove = pick End If


Case 3 'Nível de dificuldade 3

pick = MakeWinningMove


If pick = 0 Then
pick = MakeSavingMove Else
PickComputerMove = pick Exit Function
End If


If pick = 0 Then
pick = MakeSavingMove2 Else
PickComputerMove = pick Exit Function
End If


If pick = 0 Then
PickComputerMove = MakeStandardMove Else
PickComputerMove = pick End If

End Select End Function
Public Function MakeStandardMove() As Integer Dim Square As Integer
Dim pick As Integer

If Board(5) = PLAYER_NONE Then MakeStandardMove = 5
Exit Function

End If


For Square = 1 To 9 Step 2
If Board(Square) = PLAYER_NONE Then MakeStandardMove = Square
Exit Function End If
Next

For Square = 2 To 8 Step 2
If Board(Square) = PLAYER_NONE Then MakeStandardMove = Square
Exit Function

End If Next
End Function
Public Function MakeWinningMove() As Integer Dim computersquares As Integer
Dim freesquare As Integer
Dim Square As Integer Dim i As Integer

‘ Procurar uma jogada que provoque uma vitória em linha.


For Square = 1 To 7 Step 3

computersquares = 0
freesquare = 0

For i = 0 To 2

Select Case Board(Square + i)

Case PLAYER_COMPUTER
computersquares = computersquares + 1

Case PLAYER_NONE
freesquare = Square + i End Select
Next
If computersquares = 2 And freesquare <> 0 Then MakeWinningMove = freesquare
Exit Function

End If Next

‘ Procurar uma jogada que provoque uma vitória em coluna.


For Square = 1 To 3

computersquares = 0
freesquare = 0

For i = 0 To 6 Step 3

Select Case Board(Square + i)

Case PLAYER_COMPUTER
computersquares = computersquares + 1 Case PLAYER_NONE
freesquare = Square + i End Select
Next
If computersquares = 2 And freesquare <> 0 Then MakeWinningMove = freesquare
Exit Function End If
Next

‘ Procurar uma jogada que provoque uma vitória na diagonal.


computersquares = 0
freesquare = 0

For i = 1 To 9 Step 4 Select Case Board(i)
Case PLAYER_COMPUTER
computersquares = computersquares + 1 Case PLAYER_NONE
freesquare = i End Select

Next

If computersquares = 2 And freesquare <> 0 Then MakeWinningMove = freesquare
Exit Function End If

computersquares = 0
freesquare = 0

For i = 3 To 7 Step 2

Select Case Board(i)
Case PLAYER_COMPUTER
computersquares = computersquares + 1 Case PLAYER_NONE
freesquare = i End Select

Next

If computersquares = 2 And freesquare <> 0 Then MakeWinningMove = freesquare
Exit Function End If

End Function
Public Function MakeSavingMove() As Integer Dim humansquares As Integer
Dim freesquare As Integer
Dim Square As Integer Dim i As Integer

'Procurar uma jogada que impeça uma vitória em linha.


For Square = 1 To 7 Step 3

humansquares = 0
freesquare = 0

For i = 0 To 2
Select Case Board(Square + i)
Case PLAYER_HUMAN
humansquares = humansquares + 1 Case PLAYER_NONE
freesquare = Square + i End Select

Next

If humansquares = 2 And freesquare <> 0 Then MakeSavingMove = freesquare
Exit Function End If

Next

'Procurar uma jogada que impeça uma vitória em coluna.

For Square = 1 To 3

humansquares = 0
freesquare = 0

For i = 0 To 6 Step 3

Select Case Board(Square + i)
Case PLAYER_HUMAN
humansquares = humansquares + 1 Case PLAYER_NONE
freesquare = Square + i

End Select Next
If humansquares = 2 And freesquare <> 0 Then MakeSavingMove = freesquare
Exit Function End If

Next

'Procurar uma jogada que impeça uma vitória na diagonal.


humansquares = 0
freesquare = 0
For i = 1 To 9 Step 4 Select Case Board(i)
Case PLAYER_HUMAN
humansquares = humansquares + 1 Case PLAYER_NONE
freesquare = i End Select

Next

If humansquares = 2 And freesquare <> 0 Then MakeSavingMove = freesquare
Exit Function End If

humansquares = 0
freesquare = 0
For i = 3 To 7 Step 2 Select Case Board(i)
Case PLAYER_HUMAN
humansquares = humansquares + 1 Case PLAYER_NONE
freesquare = i End Select

Next

If humansquares = 2 And freesquare <> 0 Then MakeSavingMove = freesquare
Exit Function End If

End Function

Public Function MakeSavingMove2() As Integer Dim pick As Integer

Select Case Board(5) = PLAYER_HUMAN Case True

If Board(1) = PLAYER_HUMAN Then

If Board(7) = PLAYER_NONE Then pick = 7
ElseIf Board(4) = PLAYER_NONE Then pick = 4
End If

ElseIf Board(3) = PLAYER_HUMAN Then

If Board(9) = PLAYER_NONE Then pick = 9
ElseIf Board(6) = PLAYER_NONE Then pick = 6
End If

ElseIf Board(7) = PLAYER_HUMAN Then

If Board(1) = PLAYER_NONE Then pick = 1
ElseIf Board(4) = PLAYER_NONE Then pick = 4
End If

ElseIf Board(9) = PLAYER_HUMAN Then

If Board(3) = PLAYER_NONE Then pick = 3
ElseIf Board(6) = PLAYER_NONE Then pick = 6
End If End If

End Select MakeSavingMove2 = pick End Function
Public Function MakeRandomMove() As Integer

Dim pick As Integer Dim Square As Integer

Do Until pick <> 0 Square = Int(Rnd * 8) + 1
If Board(Square) = PLAYER_NONE Then pick = Square Loop
MakeRandomMove = pick End Function
Public Function CenterForm(frm As Form) frm.Left = (Screen.Width - frm.Width) / 2 frm.Top = (Screen.Height - frm.Height) / 2
End Function


This time around I wanted to convert this code to a more modern platform: Android/Java.

I won't bother you with Android/Java code. It follows the code above (also with a Game Engine implemented), but migrated to a different coding paradigm (namely OOP). A few screens:



My 4-year old kid is having a blast "playing" it...

terça-feira, junho 04, 2019

iOS vs. Android: WWDC 2019



The Good:

- Apple don't need the market to tell them what to do. In fact, they are always late to the market. I think they choose their battles wisely. Of course it's nice of the other manufactures to test the waters ahead. Will they close the gap on cost? No. But they don't need to! They are the richest company in the world. When a new Ferrari is released due say "it's amazing, but they failed to close the cost gap to the Mondeo, what a fail!".

- One of the things Apple have going for it is good quality 3rd party accessories and the security aspects. Other than that Android is streets ahead. Both these positions worry me somewhat as I no longer trust either company with the information I seem to giving them. I would be quite happy to pay X % month knowing that I will suffer no advertising my data no matter what will not be passed onto to third parties. Ideally this will be European based. I can't find anything to fit that bill. Not that I am doing anything wrong to worry either but it does sit well. Especially this smart health business. That's why I build my own ROMs for my Samsung S8. I build my own security into my smartphone!! Here's a very ancient how-to I wrote a few years ago (I must update it to the current trends in Google and Samsung; alas, no time...) 

- I think this WWDC marked the beginning of Apple slowing shifting away from Steve Jobs' legacy. Apple is integrating with more outside services (Healthkit / Homekit, 3rd party keyboards), they are updating their coding framework with the biggest changes in Apple's history (for developers) and it is clear they will keep on pushing into the 'phablet' sector, something SJ wasn't keen on.

The so-and-so:

Why on earth would Apple 'particularly' want to help their own developers write apps for their competitors? That statement goes without saying, no? iOS has been hugely attractive to developers since it was launched, just look at the stats. iOS users spend much more money on apps and more time their devices more and Android owners use theirs.

The bad:

Apple is still a niche player and it will always will be. Some 80% of smartphone users globally are on Android and this number appears to be growing. iOS/Apple on the other hand, continues to lose market share where they have dropped to a 15% global market share. In the past few years, this Apple market share number keeps falling, especially in the North America and Europe, traditional strong-holds. Apple is a pimple on the horizon in most developing economies.....India, Indonesia, Brazil, etc. Apple needed to pull out the stops to stem the blood-letting, and Android has the lion's share of the high-end market too (Samsung to name just one)! The bottom-line here is: has Apple done enough or will it be a permanent niche player? Will it always be a closed and proprietary ecosystem? It remains to be seen.


Bottom-line: Most of the early adopters of iPhone I know have now moved to Android (with one exception: a guy I work with). I think as people get more savvy, the shift to Android will just accelerate. The bottom line is that Apple is a minority player in the phone market and smartphone market. The gap is growing, too. It will continue to grow while Apple insist on such a limited range and exorbitant pricing structure. Will I ever use an iPhone? As I usually say, that depends. The moment Apple allows me to do what I can presently do with my Samsung S8 is the moment I'll leave them behind and be the first in line to buy an iPhone. Sadly that moment hasn't arrived yet as the WWDC 2019 just showed.

If you are reading this from the future: Please, please, please do not imagine we in the early XXI century were all shallow, intellectually and emotionally stunted consumer-types doing circle jerks over metal and plastic gadgets. A healthy proportion of Portugal's population in the future couldn't give a toss about all this bollocks, both iOS and Android... 

domingo, março 04, 2018

Samsung Gear S3: My First Wearable APP Using the Tizen OS by MySelfie


Samsung Gear S3 showing what it can do...

0 - Install the Development Environment with the SDK Tools (Tizen Studio 2.2 with IDE installer, Tizen Extension SDK, Samsung Accessory SDK, and the Samsung Rich Notification SDK):

1 - Install the Tizen Studio IDE;

2 - In the Tizen Studio package manager, install everything for the 2.3.2 wearable;



Tizen SDK Tools:



3 - Install the Samsung Certificate Extension;


4 - Creating the App; I chose the watch because I like all things that glitter...

Some C code spinets of the Watch Gear S3 App:




5 - Running the emulator a gazillion times (from 11:28 in the morning until 2 o'clock in the afternoon...Wife calling for lunch...) until the frigging thing was ok:

(Linux emulator kernel loading) 




6 - Find the IP on your Samsung Gear S3 given by your router:



7 - Run sdb connect 192.168.1.128 on the command prompt;

8 - Turn "debugging mode" on Gear S3;

9 - After the connection is established, use "device manager" on Tools in the Tizen Studio and install it. If you want to go the way of deploying the tpk, you can install the Watch App to a connected device with the tpk ("watchmaantao-1.0.0-x86.tpk"; (vide next screenshot). In the device list, right-click the device to which you want to install an application, and select Install app. In the file dialog, select the "watchmaantao-1.0.0-x86.tpk" file to install and click OK.


The application is installed and launched on the Samsung Gear S3:

(final version; app already with all the builtin bell and whistles that should come with every Watch app; the photos before this one belonged to the barebone version of my Watch App)



domingo, dezembro 03, 2017

Thinking in Code: "Antao's Tetris Ported from Python"


If you want to have a go at my version of the game, you can install it from here at the Google Play Store (Python version running on the Chrome Browser here).

The above app layout was modelled after my own gameboy:


Compare both pictures above. Was I successful? You tell me!

Any idiot can code, and many do. The skill is in understanding the maths and algorithms (speaking as an idiot who codes).

Lazy (or to be fair perhaps just poorly informed) people have taken to use the word "coding" as a synonym for software development. Actually, coding is tricky in and of itself (read the C++11 reference manual and tell me it ain't so) but it is still only the "bricklaying" part of construction, so to speak. Programming is creative and exploratory and stimulating to the imagination. It's a different way of thinking that serves people well in all sorts of life situations outside of software. So as a way to develop skills in logical thinking, problem solving and invention it's very useful. Not every child will go on to write software as an adult but having a basic understanding and insight into systems has to be a fundamental part of every child's education I say. If you don't understand the systems controlling your life how can you ever use them to your best advantage?

Actually the basics of code are not directly computer related at all. A simple binary device is an on-off light switch which says something like when I am 'on' my user is at home and when I am 'off' my user is away. A second light switch allows this develop into when both lights are on my user is awake and when only one light is on my user is asleep and so on. The code is what you make the light sequences mean. The same use is made of morse code, an abacus, flag signals , hand gestures, anything that can be logically explained to mean something for each different state. I think most children develop logic rather more quickly than we believe possible, and the only problem with computers is demystifying their apparent complexity when they are only ever very fast at very simple arithmetic and being given very precise instructions about what to do with all that speed adding numbers together.

I have to say that contemporary programming is much poorer than it was ten years ago, and I believe that is because we have provided far too many lazy ways to do complex things without making students graft hard at the basics and that is where I do believe improvements are to be found. However , ask a 20 something year old to sit there all day and write "select from where" ad infinitum and it doesn't take long to realise why younger people are not motivated by "heavy lifting" programming...

Programming is easy. Like any language, it is easy once you know how to talk, and think it. We have to stop thinking of programming as mathematics, science or engineering. It needs to be taught as a language skill. The moment we treat it as a language skill, the traditional barriers begin to fall. It becomes acceptable for parents of both sexes, at any age, and any religion. I don't think there are many people who would object to their kids having the opportunity to learn multiple languages, as early as possible, if they could. I don't think I have ever heard anyone object to a child being able to speak multiple languages. Once academics can get over their misconceptions on what they need programming to be, we could all move on, and start teaching our kids how to make them look stupid.

Once you can program in one language it is easy enough with the help of Google to pick up other languages. I've spent quite a lot of time programming in languages that I didn't know. In my experience what people find harder to pick up is the logic and the ability to break down the task required into the small logical steps required to make a computer perform the task. I started out very young; I learned to program because I wanted to play games and back then that meant typing in program listings from computer magazines. They never worked properly so I worked out how to fix them. Do a few of those, and you soon enough prick up how to program. After that new languages are easy. The only time I struggled a little bit was in making the leap from procedural coding to object-orientated as that's a bit of a paradigm shift.

I used to be a software developer, and have developed lots of software for the last 25 years. Believe me when I tell you that 99% of the job, has nothing to do with either mathematics, or science. The only reason you, and most other people, who probably don't program, think it does, is because everyone you ever see, working in this branch, drives that, image. Syntax is language, but expression is also language. Being able to understand, and then describe a process, is absolutely, a pure language skill. Most of the work ever done, is little more than connecting dots, and building logical expressions with existing tools and libraries. The language behind every programming language, is pretty much universal. once you have learned how to express yourself, and approach problems, you can easily skip to any language, and syntax, with a short learning curve. Ask a database developer, or a network developer how much math and science they need, to do their job. Not a lot, that is for sure. some do, but in general, very little real math is required, and it sure ain't rocket science these days. of course further skills are required in some areas, depending on what you want to do, but I would argue with anyone that this job is generally NOT science anymore. I would also argue that that math is absolutely NOT a prerequisite to be able to program today. If you are a good communicator, and you have normal math skills, you can be a great programmer. If IMO, we exclude the wrong people from programming. We need less geeks with personality disorders in this branch, and more talented communicators. To get that, we need to rethink who we think are going to be good at the job, and include a completely different skill set, as prerequisite to what makes a programmer today.

I still sometimes dream of creating some games and getting a bit of cash from it. I still tinker with Android (a few more examples of coding in Android here), and have a few half-finished games that I did in XNA for the Xbox Live Indie store. I think part of the problem for games now, or at least console games, is the publisher and retailer taking so much of the pie. Digital distribution is great in principle, but on console at least, unless you're using Xbox Live Gold or PSN+ or whatever there seems to be absolutely no discount - in fact a lot of games are more expensive than their retail counterpart (which is expensive and fickle enough). If a developer could get a lot more of the money without going through a publisher or retailer, I'd be all for it. At the moment, the vast, vast majority of games I buy are old ones (2 years old or more) that you just can't buy new, so it's all second hand. This extra money, if going to the developers themselves, would give them a lot more freedom and make conditions at them a lot more tolerable.

As for "thinking in code", I used to be the same. I could have code swimming around in my head for hours, and to an extent still do (only now, with me doing a lot of QLIK work too, a lot of mine is maps, statistics and graphs). The experience hasn't put me off playing games, but given me more respect for the people that make them - and then, sometimes, less respect when they get things wrong, especially design-wise (Dead Rising's save system, I'm looking at you).


NB: The core of the engine is the following class.

class TetrisGame implements PosPaintable {
    Grid playfield;
    TetrisPiece piece;
    int curScore;
    int px,py; 
    intNonZero testNonZero;
    intOr      putDown;

    public TetrisGame(int xs,int ys,boolean randomCrap)
{
playfield=new Grid(xs,ys,1);
clear();
piece = new TetrisPiece();
py=0;
px=(xs-piece.sizex())/2;
testNonZero = new intNonZero();
putDown = new intOr();
curScore=0;
}
    
    void clear()
{
playfield.fill(0,0,playfield.sizex(),playfield.sizey(),0);
}

    public void paint(Graphics g, int x,int y)
{
g.drawRect(x,y,2+playfield.sizex()*10,2+playfield.sizey()*10);
for(int j=0;j
    for(int i=0;i
if((playfield.grid[i][j]!=0) ||
   ((i>=px) && (i
    (j>=py) && (j
    (piece.grid[i-px][j-py]!=0)))
    g.fillRect(3+x+i*10,3+y+j*10,8,8);
        }


    public boolean step()
{
if(playfield.compare(piece,px,py+1,testNonZero))
    {
    // Put down the piece
    playfield.put_on(piece,px,py,putDown);
    // Clear out full lines
    for(int j=playfield.sizey()-1;j>=0;j--)
while(testFullLine(j)==true)
    {
    deleteLine(j);
    // Simple scoring function
    curScore+=10;
    }

            // Put on a new piece
    piece = new TetrisPiece();
    py=0;
    px=(playfield.sizex()-piece.sizex())/2;
    if(playfield.compare(piece,px,py,testNonZero))
return true;
            }
        py++;
return false;
        }

    private boolean testFullLine(int y)
{
for(int i=0;i
    if(playfield.grid[i][y]==0)
return false;
        return true;
}

    private void deleteLine(int y)
{
for(int j=y;j>0;j--)
            for(int i=0;i
playfield.grid[i][j]=playfield.grid[i][j-1];
        for(int i=0;i
    playfield.grid[i][0]=0;
        }

// Data-returning methods

    public int score()
{
return curScore;
}

// Game-play interface methods

    public void move_left(int i)
{
if(playfield.compare(piece,px-i,py,testNonZero))
    return; // Should we throw an exception here?
        px-=i;
}
    public void move_left()
{
        move_left(1);
}

    public void move_right(int i)
{
if(playfield.compare(piece,px+i,py,testNonZero))
    return; // Should we throw an exception here?
        px+=i;
}
    public void move_right()
{
        move_right(1);
}

    public void rotate_cw()
{
TetrisPiece test=new TetrisPiece(piece);
        test.rotate_cw();
if(!playfield.compare(test,px,py,testNonZero))
    piece=test;
        }

    public void rotate_ccw()
{
TetrisPiece test=new TetrisPiece(piece);
        test.rotate_ccw();
if(!playfield.compare(test,px,py,testNonZero))
    piece=test;
        }

    public void drop()
{
while(!playfield.compare(piece,px,py+1,testNonZero))
    py++;
        }







quarta-feira, julho 26, 2017

Android App: "Spinner Portuguese Style" by MySelfie


(If you want to try it, install it via Google App Store

Every time a new fad appears in the classroom, there are nay-Sayers saying how good/bad/whatever they are for children. Then they disappear, to be replaced quite quickly by something else - there usually seems to be a fad-free hiatus of anything from a couple of weeks to several months. Sometimes these fads, like these spinners, are related to things that have been around for ages, and can fulfill the same purpose, in this case the purpose fidget objects have for many people. But often kids have them simply because other kids have them. Then, of course, there are the adults who collect this sort of retro nostalgia stuff, with an attic stuffed full of Teenage Mutant Heroes cards, Moshi monsters, Star Wars memorabilia, and loom bands - but that's another story! Although they may be a fad for kids, fidget spinners for adults have been around for years. There is a fidget spinner database online that lists over 100 manufacturers. Many spinners are made of various solid metals (brass, stainless steel, titanium, and others) and cost many hundreds of dollars. Lots of different designs too. So, this isn't a fad!

But even if they were a fad, at least they wouldn't be as bad as bottle-flipping, which was the fad-du-jour late last year. How does bottle flipping work? Take any plastic drinks bottle, half fill it with water for weight, and then flip it vertically, with the aim being to have it land & stand on its base. The instability caused by the volume of water moving inside the container is what makes it a challenge. The downsides are that it's noisy (the water swishes in the bottle), it's visually distracting (flying water bottles aren't discreet), and as soon as one kid starts, every other kid in the classroom is digging in their bags to prove they can flip their own bottle better than the kid sitting next to them. Now, this is stupid!

When we were kids, for a while we used to go around with seriously powerful slingshots (with elastics made out of strips of car tire air tube) and we actually gave them up ourselves since they were seriously dangerous (as in: potentially deadly). Still, the pea shooters we mostly used in our local "wars" in the forest could potentially take an eye off if they hit directly (we used a kind of berry which was harder - and thus further flying - than peas). The point being that when pointed out to them, even kids will on their own do some level of risk reduction, just don't expect them to try go all the way to zero risk, since that almost always takes all the fun out of things. This was also stupid! Kids will be kids! Yes, someone will eventually be hurt. Unfortunately that goes for pretty much everything interesting in life:
  1. If you allow wrestling in the school gym eventually a kid will break their neck.
  2. If you allow kids to run in the playground eventually a kid will fall, crack their head badly and end up brain damaged;
  3. if you allow kids to climb trees eventually one will fall and break their spine;
  4. If you allow kids to play with toothpick and rubber bands eventually someone will lose an eye.
But the alternative is a childhood wrapped in cotton wool without climbing any trees or wrestling or running and that's a non-trivial price which gets paid by many many children for every one you save from some permanent injury or death. The rational way to approach the problem would be to quantify the risks in terms of QALYs (quality adjusted life years) or micromorts (each 1 in a million chance of death). A childhood that includes all these minor dangers has value it it's own right. It improves quality of life in a non-trivial way. But try selling that to the public : it's basically impossible to parade a million children who enjoyed their life a bit more than they would otherwise in front of the camera but easy to bring on the one poor kid with a shattered spine or a missing eye. I still fondly remember that I used to nick my granny's hairspray (those were the days) to make the best flamethrower in my neighborhood. Better than a magnifying glass for laying waste to small defenseless creatures; there was always some kid who said they knew someone who'd been killed when the flame backed up into the can and it exploded in his hand ("It's TRUE! I swear! I read about it. It happened in America."). Don't kids make their own dangerous 'toys' anymore? I also remember making a bow and arrow with a tree branch;  lollipop sticks with a pin tied to one end with cotton and a small nut for weight and cardboard flight at the other end made a great dart; best was a sewing needle with a bit of wool threaded through and then fire it off blow-dart style with a narrow tube, pea-shooter or even a Bic Biro with the refill removed. Great at school firing one off and then hiding behind the desk lid.

Come September, the spinners will be forgotten by 90% of kids. At this time of year, shops have to be very careful with these things, because we're only a couple of months into the summer and they need to have enough in stock to milk the so-called fad, but not have too many left by the time the school start in September. Otherwise they will stuck with hundreds of spinners that no one will want any more, and they'll have to clear the shelf of all the left over loom bands to find somewhere to put them.

Not so with my version of the Spinner. It's here to stay. My little boy has been having a ball playing with it on his mother's smartphone. He keeps on asking for it in Manelês: "Pai, quéo spinna" ("Dad, I want spinner"; sorry, I cannot give a proper translation in English, but you get the gist)...

What do I need to go about it? Find a couple of equations regarding the angular momentum and the Force applied on the spinner. The rest is just code...Link on Google Play Store above if you care to try it.



r, radius of the object's circular motion
T, The cycle of the object's circular motion

quinta-feira, dezembro 08, 2016

Android App: "Messenger App for Drivers"

Follow my blog with Bloglovin
(If you want to try it, install it via Google App Store


In the beginning of the universe I was hoping to use messenger to send/receive Google Voice texts and "Google Voice" app to check voicemail. Messenger as a redundant app to send/receive carrier texts is not useful. That's why I started using only text with my "Google Voice" number. The cruz of the matter is that the "Google Voice" app is not very good for texting. The texts are not grouped properly. Texting (or messaging) is meant to be asynchronous. This makes chit-chat possible in terms of having a conversation take place over several days. The "Google Voice" app cuts this chit-chat into many entries that should be placed together. When I ask someone a question about something on Wednesday night, and they don't answer back until Saturday morning, I expect that communication to be contained in just one entry. Fat chance! I think that the "Google Voice" app is only good for voicemail. I also like the transcription and playback without having to "call in" to get it, but that's as far as it goes liking-it-wise.

What about "Hangouts"? I can use "Hangouts" for texting with "Google Voice", but that means  I can't see the voicemail anymore, because voicemail is entered into the same container list as the texts and can't be split. Who was the genius at Google to think this through?? If I choose to use hangouts, then a banner is placed inside the "Google Voice" app (don't forget I' also trying to check voicemail) prompting me to either open "hangouts" or quit using it altogether. I know what you're thinking. Get rid of the banner. Nope! I can't remove this banner. This gets translated into the fact that "Google Voice" app cannot be used in a productive manner, as far as I'm concerned!!! I was hoping to use "Messenger" to send/receive "Google Voice" texts and "Google Voice" app to check voicemail. Forget it!

I actually use my Google Voice number primarily and I did that to keep things less baffling and to keep one number forever, but as of late, Google has just made things more complicated especially since "Google Messenger" does not support "Google Voice". It's ludicrous that I've to get a carrier number to pay for and then use it with free messenger (Google Messenger is even advertising on Google Hangouts for a product that doesn't support Google Voice...!!)

There are now 3 separate google apps for texting and still no good way to do it for Google Voice.

Because of this I decided to make my own messaging app based on the "Google Speech Recognition Engine/API" to be used when I'm on the go (e.g., driving). It's still a work-in-progress. More features in the works to be released in 2017. It's a disgrace that only in 2016 Google opened up its speech recognition API to third-party developers. I'm sure will see Google pricing it at a later date just to fuck us up. Let me enjoy it while it lasts...

For the record, Apple's virtual assistant Siri’s voice recognition capabilities pale in comparison to Google’s. We've yet to see an API for developers to use the Siri tech in their own apps. Not that I'm thinking of switching to the crappy dark side...I much prefer staying on the good side, even with all Google's shenanigans in place...