minmax algorithm with tictactoe, wrong decision - algorithm

I have this code written in Dart that implements the minmax algorithm, With a tic-tac-toe, the computer is playing as "O" and trying to maximize the score, but I get some wrong decision like this, it says (look at the top, the first is the move coordinate and the second is the score) that I have to move in (0,2). But this is not the right decision.
This is my code:
class Ai {
play(state) {
return max_Value(state);
}
// the action parameter holds the move that got as to this state
List max_Value(List state, {action}) {
List v = [null, double.negativeInfinity];
if (terminal(state)) {
return [action, utility(state)];
}
for (var action in actions(state)) {
if (v[1] == 1) return v;
v = max(v, min_Value(result(state, action), action: action));
}
return v;
}
List min_Value(List state, {action}) {
List v = [null, double.infinity];
if (terminal(state)) {
return [action, utility(state)];
}
for (var action in actions(state)) {
if (v[1] == -1) return v;
v = min(v, max_Value(result(state, action), action: action));
}
return v;
}
List min(List prv, List curr) {
return prv[1] < curr[1] ? prv : curr;
}
List max(List prv, List curr) {
return prv[1] > curr[1] ? prv : curr;
}
bool terminal(List state) {
if (state[0][0] == state[0][1] &&
state[0][0] == state[0][2] &&
state[0][0] != "") {
return true;
}
if (state[1][0] == state[1][1] &&
state[1][0] == state[1][2] &&
state[1][0] != "") {
return true;
}
if (state[2][0] == state[2][1] &&
state[2][0] == state[2][2] &&
state[2][0] != "") {
return true;
}
// vertical
if (state[0][0] == state[1][0] &&
state[0][0] == state[2][0] &&
state[0][0] != "") {
return true;
}
if (state[0][1] == state[1][1] &&
state[0][1] == state[2][1] &&
state[0][1] != "") {
return true;
}
if (state[0][2] == state[1][2] &&
state[0][2] == state[2][2] &&
state[0][2] != "") {
return true;
}
// diagonal
if (state[0][0] == state[1][1] &&
state[2][2] == state[0][0] &&
state[0][0] != "") {
return true;
}
if (state[2][0] == state[1][1] &&
state[2][0] == state[0][2] &&
state[2][0] != "") {
return true;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "") {
return false;
}
}
}
return true;
}
double utility(List state) {
String winner = "";
// horizontal
if (state[0][0] == state[0][1] && state[0][0] == state[0][2]) {
winner = state[0][0];
}
if (state[1][0] == state[1][1] && state[1][0] == state[1][2]) {
winner = state[1][0];
}
if (state[2][0] == state[2][1] && state[2][0] == state[2][2]) {
winner = state[2][0];
}
// vertical
if (state[0][0] == state[1][0] && state[0][0] == state[2][0]) {
winner = state[0][0];
}
if (state[0][1] == state[1][1] && state[0][1] == state[2][1]) {
winner = state[0][1];
}
if (state[0][2] == state[1][2] && state[0][2] == state[2][2]) {
winner = state[0][2];
}
// diagonal
if (state[0][0] == state[1][1] && state[2][2] == state[0][0]) {
winner = state[0][0];
}
if (state[2][0] == state[1][1] && state[2][0] == state[0][2]) {
winner = state[2][0];
}
if (winner == "O") {
return 1;
} else if (winner == "X") {
return -1;
} else {
return 0;
}
}
List actions(List state) {
List acs = [];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "") {
acs.add([i, j]);
}
}
}
return acs;
}
List result(List state, List action) {
List newState = [
["", "", ""],
["", "", ""],
["", "", ""]
];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
newState[i][j] = state[i][j];
}
}
newState[action[0]][action[1]] = player(state);
return newState;
}
player(List state) {
int xnum = 0;
int onum = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == "X") {
xnum++;
} else if (state[i][j] == "O") {
onum++;
}
}
}
if (xnum > onum) {
return "O";
} else {
return "X";
}
}
}

Some mistakes:
This needs to depend on the player to move whether you return max or min:
play(state) {
return max_Value(state);
}
Here (and same for min) v might become an action done later and not the actual action that was performed and lead to the better value.
v = max(v, min_Value(result(state, action), action: action));
Possible improvements:
With a little modification terminal could return the evaluation too and then you don't need the utility function.
You constantly evaluate player with the function. You should have to do that at most once (see first mistake). min and max know whether they are playing X or O. Everything could be simplified a lot and the number of functions reduced without increasing their complexity.

Related

Read access violation of std::shared_ptr

I'm working on a personal project using SFML and C++. The project has an interface and some buttons. So... I have a SortingAlgorithms class, which will be a base class and a subclass BubbleSort
class SortingAlgorithms
{
protected:
std::vector<sf::RectangleShape> sequence;
sf::RenderWindow& window;
int minimum, maximum;
int elements;
public:
SortingAlgorithms();
// Class constructor which initializes a sequence
SortingAlgorithms(int min, int max, int els, sf::RenderWindow& win);
std::vector<sf::RectangleShape> GetSequence() const;
// A pure virtual function for overriding
virtual void Sort(std::unique_ptr<Interface>& init) = 0;
// A method for printing the sequence
void Print(std::unique_ptr<Interface>& init);
};
class BubbleSort : public SortingAlgorithms
{
public:
BubbleSort(int min, int max, int els, sf::RenderWindow& win);
void Sort(std::unique_ptr<Interface>& init);
};
The main problem is in the Sort method which has some button events too. What I am trying to do in this method is simply printing a sequence or a sorted sequence using an std::shared_ptr(generatedAlg) which will be initialized on this branch if (selectedAlg == "Bubble Sort"); everything works fine but if it gets to this point if ((*it).DetectButton(window) == true && (*it).GetButton() == "Sort") I get
Exception thrown: read access violation.
std::shared_ptr<SortingAlgorithms>::operator-><SortingAlgorithms,0>(...) returned nullptr.
Similarly happens when I try to allocate it manually too :
Run-Time Check Failure #3 - The variable 'generatedAlg' is being used without being initialized.
Is there any way to solve this issue?
void Interface::ConfigBar(std::unique_ptr<Interface>& init)
{
while (window.isOpen())
{
sf::Event event;
std::shared_ptr<SortingAlgorithms> generatedAlg;
while (window.pollEvent(event))
{
for (std::vector<Button>::iterator it = configButtons.begin(); it != configButtons.end(); it = std::next(it))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
case sf::Event::MouseMoved:
if ((*it).DetectButton(window) == true)
{
(*it).SetTextColor(sf::Color::White);
}
else
{
(*it).SetTextColor(sf::Color::Black);
}
break;
case sf::Event::MouseButtonPressed:
if ((*it).DetectButton(window) == true && (std::distance(configButtons.begin(), it) != 5 && std::distance(configButtons.begin(), it) != 6 && std::distance(configButtons.begin(), it) != 9))
{
(*it).SetShapeColor(sf::Color(0, 109, 119));
}
break;
case sf::Event::MouseButtonReleased:
if ((*it).DetectButton(window) == true && (std::distance(configButtons.begin(), it) != 5 && std::distance(configButtons.begin(), it) != 6 && std::distance(configButtons.begin(), it) != 9))
{
(*it).SetTextColor(sf::Color::Black);
(*it).SetShapeColor(sf::Color(42, 157, 143));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == ">")
{
inputMin += 10;
configButtons.at(5).SetButton(std::to_string(inputMin));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "<")
{
inputMax += 10;
configButtons.at(6).SetButton(std::to_string(inputMax));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "+")
{
inputEls += 1;
configButtons.at(9).SetButton(std::to_string(inputEls));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "-")
{
inputEls -= 1;
if (inputEls < 0)
{
inputEls = 0;
std::cerr << "Cannot be less than 0" << std::endl;
}
configButtons.at(9).SetButton(std::to_string(inputEls));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "Reset")
{
inputMin = 0;
inputMax = 0;
inputEls = 0;
configButtons.at(5).SetButton(std::to_string(inputMin));
configButtons.at(6).SetButton(std::to_string(inputMax));
configButtons.at(9).SetButton(std::to_string(inputEls));
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "Generate")
{
if (inputMin == 0 || inputMax == 0 || inputEls == 0)
{
std::cout << "Cannot generate a sequence by default configuration" << std::endl;
break;
}
if (selectedAlg == "Bubble Sort")
{
generatedAlg = std::make_shared<BubbleSort>(inputMin, inputMax, inputEls, window);
generatedAlg->Print(init);
}
std::cout << "Sequence generated" << std::endl;
}
if ((*it).DetectButton(window) == true && (*it).GetButton() == "Sort")
{
//generatedAlg = std::make_shared<BubbleSort>(inputMin, inputMax, inputEls, window);
generatedAlg->Sort(init);
std::cout << "The sequence is now sorted" << std::endl;
}
case sf::Event::KeyPressed:
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
{
if (algorithmType == "Sorting Algorithms")
SortingAlgMenu(init);
PathAlgMenu(init);
}
break;
default:
break;
}
}
}
window.clear(sf::Color(sf::Color::White));
for (std::vector<Button>::iterator it = configButtons.begin(); it != configButtons.end(); it = std::next(it))
{
(*it).Draw(window);
}
window.display();
}
}

Test case neither passes nor fails in VS

In VS Express 2013, I run the following program against certain test cases written in a spec file. The code and a portion of the spec file is as follows:
struct DOB {
int date;
int month;
int year;
};
int stringToValue(char* temp) {
int num = 0;
while (*temp != '-' && *temp != '\0') {
if (((*temp) >= '0') && ((*temp) <= '9')) {
num = num * 10 + ((*temp) - '0');
++temp;
}
}
return num;
}
int isValidFormat(char* dob) {
int length = 0;
for (int i = 0; dob[i] != '\0'; ++i) {
if (!((dob[i] >= '0' && dob[i] <= '9' || dob[i] == '-')))
return 0;
++length;
}
return length;
}
int function(int value1, int value2) {
if (value1>value2) {
return 2;
}
else if (value1<value2) {
return 1;
}
else
return 0;
}
int isLeap(int year) {
if ((year % 4 == 0) && !(year % 100)) {
return 1;
}
else {
if (year % 400 == 0)
return 1;
else
return 0;
}
}
int isValid(struct DOB d) {
if (d.year>0) {
if (d.month>0 && d.month <= 12) {
if (d.month == 2 && isLeap(d.year) == 1) {
if (d.date>0 && d.date <= 29) {
return 1;
}
else if (d.date > 0 && d.date <= 28) {
return 1;
}
else
return 0;
}
else if (d.date == 1 || d.date == 3 || d.date == 5 || d.date == 7 || d.date == 8 || d.date == 10 || d.date == 12){
if (d.date > 0 && d.date <= 31) {
return 1;
}
else
return 0;
}
else {
if (d.date > 0 && d.date <= 30) {
return 1;
}
else
return 0;
}
}
else {
return 0;
}
}
else {
return 0;
}
}
int isOlder(char* dob1, char* dob2) {
struct DOB d1, d2;
if (isValidFormat(dob1)!= 10 && isValidFormat(dob2) != 10)
return -1;
d1.date = stringToValue(dob1);
d2.date = stringToValue(dob2);
d1.month = stringToValue(dob1 + 3);
d2.month = stringToValue(dob2 + 3);
d1.year = stringToValue(dob1 + 6);
d2.year = stringToValue(dob2 + 6);
if (isValid(d1) == 1 && isValid(d2) == 1) {
if (function(d1.year, d2.year) != 0)
return function(d1.year, d2.year);
else if (function(d1.month, d2.month) != 0)
return function(d1.month, d2.month);
else
return function(d1.date, d2.date);
}
else {
return -1;
}
}
In the spec file containing test cases:
TEST_METHOD(isOlderinvalid)
{
Assert::AreEqual(-1, isOlder("1000", "15-07-2000"), L"isOlder: invalid input case failed", LINE_INFO());
Assert::AreEqual(-1, isOlder("15-07-2000", "000"), L"isOlder: invalid input case failed", LINE_INFO());
Assert::AreEqual(-1, isOlder("15-0A-2000", "15-07-2000"), L"isOlder: invalid input case failed", LINE_INFO());
Assert::AreEqual(-1, isOlder("15-13-2000", "15-07-2000"), L"isOlder: invalid input case failed", LINE_INFO());
Assert::AreEqual(-1, isOlder("29-02-2001", "15-07-2000"), L"isOlder: invalid input case failed", LINE_INFO());
}
When I run the following test cases on my local compiler, I get the expected output. But when I run the tests on the above code, I neither pass nor fail the above test cases. I'm honestly not sure what's wrong. It seems like a VS-specific problem rather than a problem with my code.
Wrong error condition
// if (isValidFormat(dob1)!= 10 && isValidFormat(dob2) != 10)
if (isValidFormat(dob1)!= 10 || isValidFormat(dob2) != 10)
return -1;
When only 1 format was invalid, code called weak function stringToValue() which has an infinite loop with invalid input.
int stringToValue(char* temp) {
int num = 0;
while (*temp != '-' && *temp != '\0') {
if (((*temp) >= '0') && ((*temp) <= '9')) {
num = num * 10 + ((*temp) - '0');
++temp; // Move this to outside `if()` test
}
}
return num;
}
Perhaps additional problems.
Unclear how code "worked" on OP's local compiler. Maybe Assert() was not active.

simulating centipede finite state machine

I'm trying to write a centipede game clone, and I have written a node class which is basically a circle.
I'm trying to write an FSM to simulate node movements and bouncing with bricks or the screen, but the problem, that the FSM conflicts with other conditions. How would I resolve it ? For example one of the nodes can be at x <0 but they have y > 800.
public function gameLoop(event:Event):void
{
for (var i:int = 0; i < m_nodes.length; i++)
{
if (m_nodes[i].x > 750)
{
m_nodes[i].current_dir = Node.Direction_RIGHT;
}
else if (m_nodes[i].x < 10)
{
m_nodes[i].current_dir = Node.Direction_UP;
}
if ( m_nodes[i].y < 0 )
{
m_nodes[i].current_dir = Node.Direction_RIGHT;
}
else if ( m_nodes[i].y > 590 )
{
m_nodes[i].current_dir =Node.Direction_LEFT;
}
if (m_nodes[i].hitTestObject(m_bricks[i]))
{
//m_nodes[i].current_dir = Node.Direction_RIGHT;
}
if (m_nodes[i].current_dir == Node.Direction_LEFT)
{
m_nodes[i].vx = -5;
m_nodes[i].vy = 0;
}
if (m_nodes[i].current_dir == Node.Direction_RIGHT)
{
m_nodes[i].vx = 0;
m_nodes[i].vy = 5;
}
if (m_nodes[i].current_dir == Node.Direction_UP)
{
m_nodes[i].vx = 0;
m_nodes[i].vy = -5;
}
m_nodes[i].x += m_nodes[i].vx;
m_nodes[i].y += m_nodes[i].vy;
}
}
Update: new updated code, with fixing the logic, but collision detects fails, the state machines have conflict states.
for (var i:int = 0; i < m_nodes.length; i++)
{
if (m_nodes[i].x > 750)
{
m_nodes[i].current_dir = Node.Direction_DOWN;
}
else if (m_nodes[i].x < 40 && m_nodes[i].y < 600)
{
if (!m_nodes[i].current_dir == Node.Direction_RIGHT)
{
m_nodes[i].current_dir = Node.Direction_UP;
trace("dir up");
}
}
if (m_nodes[i].hitTestObject(m_bricks[i]) )
{
trace("hit");
m_nodes[i].vx = 0;
m_nodes[i].vy = 5;
}
if (m_nodes[i].y < 40 && m_nodes[i].x < 40)
{
m_nodes[i].current_dir = Node.Direction_RIGHT;
}
else if (m_nodes[i].y > 560 && m_nodes[i].x > 40)
{
m_nodes[i].current_dir = Node.Direction_LEFT;
}
if (m_nodes[i].current_dir == Node.Direction_LEFT)
{
m_nodes[i].vx = -5;
m_nodes[i].vy = 0;
}
else if (m_nodes[i].current_dir == Node.Direction_DOWN)
{
m_nodes[i].vx = 0;
m_nodes[i].vy = 5;
}
else if (m_nodes[i].current_dir == Node.Direction_RIGHT)
{
m_nodes[i].vx = 5;
m_nodes[i].vy = 0;
}
if (m_nodes[i].current_dir == Node.Direction_UP)
{
m_nodes[i].vx = 0;
m_nodes[i].vy = -5;
}
m_nodes[i].x += m_nodes[i].vx;
m_nodes[i].y += m_nodes[i].vy;
}

Algorithm to determine status of a TicTacToe game?

I have a program that allows 2 players to play TicTacToe. After each player makes a move, it should display the board at that point and return an enumaration called Status that show whether the players should continue, if a player won, or if it's a draw. However, the algorithm either return a StackOverflowError, or continues input. Here is the algorithm I used.
//Checks for winner by rows
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 1; j++) {
if (board[i][j] == 'X') {
if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
} else if (board[i][j] == 'O') {
if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) {
printStatus(2);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
}
}
//Checks for winner by columns
for (int i = 0; i < 1; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == 'X') {
if (board[i][j] == board[0 + 1][j] && board[i][j] == board[0 + 2][j]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
} else if (board[i][j] == 'O') {
if (board[i][j] == board[0 + 1][j] && board[i][j] == board[0 + 2][j]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
}
}
//This group of if statements boards for winner diagnolly
if (board[0][0] == 'X') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}else if (board[0][0] == '0') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
if (board[0][2] == 'O') {
if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}else if (board[0][2] == 'X') {
if (board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
printStatus(1);
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
Here is the printStatus method.
private void printStatus(int player) {
Status status = gameStatus();
if (status == Status.DRAW) {
System.out.println("The game has ended in a draw.");
System.exit(0);
} else if (status == Status.WIN) {
System.out.println("Player " + player + " has won the game.");
System.exit(0);
} else if (status == Status.CONTINUE) {
System.out.println("The game continues.");
play();
}
}
Here is the error:
Exception in thread "main" java.lang.StackOverflowError
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:86)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:92)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
at tictactoe.TicTacToe.gameStatus(TicTacToe.java:92)
at tictactoe.TicTacToe.printStatus(TicTacToe.java:69)
And so forth
Your problem is that you have code that repetitively calls itself creating a never-ending cycle. For example, if method A() has code that calls method B(), but within B(), there is code that calls A(), then the code will run infinitely as A() invokes B(), which then invokes A() again with the cycle repeating. StackOverflow errors are often indicative of this.
In your case, it's because your function gameStatus() (which, I assume is the first part of code you posted), calls printStatus(), which then calls gameStatus() again in the line Status status = gameStatus();
Try passing the status as an argument in printStatus, like printStatus(2,Status.WIN);, instead of trying to get the return of gameStatus within printStatus.
There does not appear to be any code in what you posted that would cause a StackOverflowError (unless you're doing something really weird in printStatus). The error causing that must be somewhere else in your code. So, unfortunately, unless you post more code, I can't help.
However, here are two things I noticed you could use some improvement on. First, (the way you're implementing this) you do not need nested for loops. The loops beginning with for (int j = 0; j < 1; j++) {, and with for (int i = 0; i < 1; i++) {, are not necessary, and they cause errors, as they produce checks where only two boxes are checked, instead of three in a row. You can simplify them by simply eliminating those loops. (I also modified your if statement, see below for more detail).
//Checks for winner by rows
for (int i = 0; i < 3; i++) {
if (board[i][j] == board[i][0 + 1] && board[i][j] == board[i][0 + 2]) { //Check if one player has matched a row
if (board[i][j] == 'X') { //Then check which player won
printStatus(1);
}
else{
printStatus(2);
}
return Status.WIN;
} else {
return Status.CONTINUE;
}
}
You can also simplify your if statement by only checking for whether X or 0 occupy a space, after you have figured out someone won. So, for example, instead of doing
if (board[0][0] == 'X') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
}
//More code here
}
else if (board[0][0] == 'O') {
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
printStatus(1);
}
//More code here
}
You can simply the code by changing it to:
if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) { //Check if first diagonal is complete
if (board[0][0] == 'X') { //Check who won
printStatus(1);
}
else{
printStatus(1);
}
return Status.WIN;
} else {
return Status.CONTINUE;
}
In this way, the statement if (board[0][0] == board[1][1] && board[0][0] == board[2][2]) is only executed once, and the second statement, if (board[0][0] == 'X'), is only executed if someone has won the diagonal. In your implementation, the first check of if (board[0][0] == 'X') will be run, then either the interior if statement, or it will execute the second player check, if (board[0][0] == 'O'), then the interior one. In this way, your code will have to run between 2 and 3 different statements, whereas in mine, it's between 1 and 2 (with two only occurring when a player has won).

Is there email validator code for Java ME or BlackBerry?

Is there some standard email validator code sample for Java ME or BlackBerry?
public static boolean validateEmailID(String email) {
email = email.trim();
String reverse = new StringBuffer(email).reverse().toString();
if (email == null || email.length() == 0 || email.indexOf("#") == -1) {
return false;
}
int emailLength = email.length();
int atPosition = email.indexOf("#");
int atDot = reverse.indexOf(".");
String beforeAt = email.substring(0, atPosition);
String afterAt = email.substring(atPosition + 1, emailLength);
if (beforeAt.length() == 0 || afterAt.length() == 0) {
return false;
}
for (int i = 0; email.length() - 1 > i; i++) {
char i1 = email.charAt(i);
char i2 = email.charAt(i + 1);
if (i1 == '.' && i2 == '.') {
return false;
}
}
if (email.charAt(atPosition - 1) == '.' || email.charAt(0) == '.' || email.charAt(atPosition + 1) == '.' || afterAt.indexOf("#") != -1 || atDot < 2) {
return false;
}
return true;
}
Use this code for checking the given email id is valid or not,
private static boolean validateEmailID(String email) {
if (email == null || email.length() == 0 || email.indexOf("#") == -1 || email.indexOf(" ") != -1) {
return false;
}
int emailLenght = email.length();
int atPosition = email.indexOf("#");
String beforeAt = email.substring(0, atPosition);
String afterAt = email.substring(atPosition + 1, emailLenght);
if (beforeAt.length() == 0 || afterAt.length() == 0) {
return false;
}
if (email.charAt(atPosition - 1) == '.') {
return false;
}
if (email.charAt(atPosition + 1) == '.') {
return false;
}
if (afterAt.indexOf(".") == -1) {
return false;
}
char dotCh = 0;
for (int i = 0; i < afterAt.length(); i++) {
char ch = afterAt.charAt(i);
if ((ch == 0x2e) && (ch == dotCh)) {
return false;
}
dotCh = ch;
}
if (afterAt.indexOf("#") != -1) {
return false;
}
int ind = 0;
do {
int newInd = afterAt.indexOf(".", ind + 1);
if (newInd == ind || newInd == -1) {
String prefix = afterAt.substring(ind + 1);
if (prefix.length() > 1 && prefix.length() < 6) {
break;
} else {
return false;
}
} else {
ind = newInd;
}
} while (true);
dotCh = 0;
for (int i = 0; i < beforeAt.length(); i++) {
char ch = beforeAt.charAt(i);
if (!((ch >= 0x30 && ch <= 0x39) || (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x61 && ch <= 0x7a)
|| (ch == 0x2e) || (ch == 0x2d) || (ch == 0x5f))) {
return false;
}
if ((ch == 0x2e) && (ch == dotCh)) {
return false;
}
dotCh = ch;
}
return true;
}
You can simply google around for email validation regex pattern. Thats the easiest and efficient way to check email string format. see the link below.
http://www.zparacha.com/ultimate-java-regular-expression-to-validate-email-address/
http://leshazlewood.com/2006/02/04/java-email-address-validation-the-right-way-regular-expression/
You will find many other examples for regex. For Regex, check the following link.
http://www.regular-expressions.info/java.html

Resources