Interprocess communication between multiple AI engines - artificial-intelligence

I want to arrange an AI contest between some friends.
Lets say tic tac toe,
each player program a method which get the board and a symbol(X\O) and return the place which he want to play at his turn.
Now my problem its how to "connect" two AI's in another program so I can test all users and see who has the best code.
The only way I think of is to communicate with a text file - all the AI's have thread running on background and check changes on the text file,the engine summary the game details(which turn,the board,score,players) to the text file.
How can this can be done better?
And one more little thing, this is common to have a time frame for each turn in AI contests?
(Because the AI program will run in different times on different computers)

It isn't clear from your question whether this has to be performed online or not.
If you're after finding "the best Tic Tac Toe algorithm", you could simply:
(This may slightly differ, depending on the programming language)
Define an interface (e.g: ITicTacToeSolver)
Have all your friends implement it in their own way and send you a DLL with their solution.
Create the game which will dynamically load these DLLs, and test them (play 1,000,000 games with the algorithm that is loaded).
Keep track of game statistics to see which algorithm is best.

If the AI programs are competing in a game like tic tac toe, typically every program would have limited total "thinking" time (e.g. 5 minutes), and a program that exceeds its time allotment would lose.
Typically often the programs are connected over some sort of a simple protocol, not through text files. The protocol can run on standard I/O or through TCP/IP sockets.
To normalize CPU usage, you can request that for tournament games, all the programs are compiled to work on a reference platform and then you provide two identical PCs, both running one of the active contestants. It then becomes a requirement of your tournament that the programs can be executed on this reference platform.

Use an interface and a standard programming language - so you can forget about text files and bollocks like that.

Figure out a simple SOAP protocol. You can simply create a WSDL interface - easy to create using windows communication foundatoin (WCF) or JMS.
Easiest would be to have a centralized server to serve as a referee and keep track of time. Each player could be assigned an ID.
Then you could have a the following interface (use WCF or JMS to create a WSDL SOAP protocol)
function int requestGame(int opponentID, int color)
- if called with color = -1, randomly assigns a color and returns it (0=white, 1=black).
- otherwise you can request a color, and returns it if accepted, -1 if not accepted.
- could use -1 to request random opponent.
function int getRemainingTime(int color)
- returns the time remaining on clock for color
function bool play(int color, int i, int j)
where color = 0 - white - 1 black,
i, j are board coordinates,
- returns true if it is a legal move
function bool won(int color)
- returns true if color has won the game.
Not having a centralized server would be more complex since they would have to negotiate over agreed wins, time, etc.

I would suggest to have each of the AI be executable files, communicating by using standard input and output. The game engine (the referee) would send the complete state of the world to AI_one as input, then wait for a move from standard output. It would then perform the move (if legal) and repeat the process for AI_two, then alternate between the two until the game is over. As a failsafe the referee can make one side lose if it takes too long to make a move.
This method is used by Google AI challenge.
One very big advantage to this approach is that people can write their AI in different languages, as long as they follow the agreed standard for how to make a move.

If your goal is to have an AI programming competition amongst friends, I'd suggest that you don't waste time designing and implementing the framework for holding the competition. Use something that already exists for that purpose. You can skip all the pain and heartache of fixing bugs in your framework and get right to the fun part: developing AI.
A good framework is the Robocode game. Watching your robots kill each other will be a lot more fun than watching them play tic-tac-toe.

You should take a look at this question:
What is the best Battleship AI?
In it he creates a battleship AI contest / challenge. It was very high rated and a lot of fun to code for and watch.
He used the Tournament API http://tournaments.codeplex.com/ to run the competition.
Also, it's important to allow the submissions to compete multiple times.. ie 1000 times each. This removes alot of the randomness and luck from the competitors.

Related

Why is the result of minimax of tic-tac-toe always a draw?

I found the below text from here, saying that the result for minimax for games like tic-tac-toe and chess will always be a draw. I also saw minimax algorithms for unbeatable tic-tac-toe. But I don't quite understand the reason why minimax results in a draw. Is it because there is no guaranteed winning or losing move and thus the best possible option for both players is a draw?
a computer running a minimax algorithm without any sort of enhancements will discover that, if both it and its opponent play optimally, the game will end in a draw no matter where it starts, and thus have no clue as to which opening play is the "best." Even in more interesting win-or-lose games like chess, even if a computer could play out every possible game situation (a hopelessly impossible task), this information alone would still lead it to the conclusion that the best it can ever do is draw (which would in fact be true, if both players had absolutely perfect knowledge of all possible results of each move).
The information from the site you’ve linked is slightly incorrect.
We know from a brute-force exploration of the game that with perfect play tic-tac-toe will always end in a draw. That is, if both players play the game according to the best possible strategy, then the game ends in a draw. There’s a wonderful xkcd graphic that details how to play perfectly.
If you were to run a minimax search over the game all the way to the end, it isn’t necessarily the case that minimax won’t know what option to pick. Rather, minimax would select any move that leads to a forced draw, since it always picks a move that leads to the best possible result for the player. It’s “unbeatable” in the sense that a perfect minimax player will never lose and, if you play against it with a suboptimal strategy, it may be able to find a forced win and beat you.
As for chess - as of now (December 2021) no one knows whether chess ends in a draw with perfect play or whether one of the players has a forced win. We simply aren’t able to explore the game tree in that much depth. It’s entirely possible that white has a forced win, for example, in which case a minimax search given sufficient time and resources playing as white will always outplay you.

How does one go about creating and accessing a small server with Unity?

I was initially going to write what looked like a four paragraph essay to explain what I'm working on, but it wasn't nessecary. In summary, I'm a rookie at Unity and know very little about how to create a platform in which I can store(send and retrieve from other clients) data in "the cloud". Yet, I need to be able to do so for my project.
using System.Collections.Generic;
using UnityEngine;
public class MultiplayerMoveMe : MonoBehaviour
{
//Note: I am making a retro-style game where all sprites face the camera, so the rotation of the players is not a factor that needs considering here; just the position.
//I have a fleshed-out idea on how I will do all of this, however I am completely foreign in all things server-related on this scale so I need some assistance(not the most prideful circumstances).
public GameObject p2Obj;
void Start()
{
//Anything that I might need to add that the serverGet() function might require
}
void serverGet(int playerNum, string reqType)
{
//On their side, every frame, the second player's X, Y, and Z pos should be packed into a string with seperator char '|' and then filed on the server under playerdata/2/pos/
//Then, this script(on the side of player 1) would(every frame, displaced by +1 frame initially) take the player number and the reqType to find said directory online with THIS function to return the value.
//Funny thing is; I have no idea what I'm doing.
//And no, I haven't connected to a server yet. I also want to stay away from any third party apps for this since this is small-scale and I only wish to learn the ins and outs of all of this.
}
void Update()
{
String p2Position = serverGet(2,"pos");
// String p2Position's value is currently "x|y|z"
String[] sl = p2Position.Split('|');
float xPos = float.parse(sl[0]);
float yPos = float.parse(sl[1]);
float zPos = float.parse(sl[2]);
// Now that all values are floats, we can feed them into the thingamabobber to change the position of the other player from our side.
p2Obj.transform.position = new Vector3(xPos, yPos, zPos);
}
}
Below I have a script which, if the serverGet() function's contents were actually existant(and functional, of course), would set the position of the second player to their position according to the data online, which the instance from their side submits in the first place(every frame as well, -1 frame initial displacement so that everything works). This way, if I move on one computer as "player 2", the computer in which I am playing as "player 1" will show the movement of player 2 as it progresses every frame. In other words, basically all calculation is client-side, but the actual communication is(unavoidably) server-side. That server-side is what I'm clueless about, and would appreciate if anyone here could lead me a step in the right direction.
As for the script that actually submits the terms to the server, that will come with my understanding of all of this; which again, I don't have as of right now.
There seems to have been a number of questions lately: "So I'm gonna write a MP game engine from scratch!" (Example.)
To get some basic grounding in mmp engineering, first spend a few days working with Unity's system https://docs-multiplayer.unity3d.com
Do try to understand the scale of your problem. You're about to embark on a PhD level enterprise that will take months of full-time work at the minimum. It would be insanity to not, first, spend a few days with current systems to gain some basic principles.
Similarly, Photon is very popular for mmp systems, https://www.raywenderlich.com/1142814-introduction-to-multiplayer-games-with-unity-and-photon next spend a few days making toy Photon/Unity systems to learn more.
Finally Mirror networking is the one that is "like Unity's old networking" https://assetstore.unity.com/packages/tools/network/mirror-129321 so really you should try that a little too.
Finally on the face of it to literally answer your question as is, click over to AWS, spin up some ubuntu EC2 instances, and start work on a "simple" game server, so almost certainly you'd use Node/Express/SQL and likely websockets (just to get started, you'd have to move to raw udp communications eventually). It's just not realistic to start doing that though until you familiarize yourself with some basic existing systems.

Find the uniform search technique for the River Crossing puzzle

I have to use a uninformed search technique to solve the following problem.
The game is like:
On side of the river, there is a Policeman, a Robber, a woman in a red-dress and her two children, a woman in a yellow dress and her two children. There is a boat that can carry atmost two persons. The children cannot drive the boat.
If the policeman is absent then the robber will kill the people. If the red-dress woman is absent then the yellow-dressed woman will kill the red-dressed woman’s children and vice versa.
I am confused as usual. Please help me figure it out.
The problem and how can it be solved (without programming) is shown in the video below:
https://www.youtube.com/watch?v=vSusAZBSWwg
Thank you.
Problems like River Crossing Puzzle, Sokoban or Lemmings are solved normally with Brute-Force-Search in the gametree. The domain is specified declarative as rules (moves are possible or not), and a function which determines the amount of points which are reached by a policy (policy = plan through the gametree). The solver has the aim to find a good policy. The best hardware for doing this is a quantum computer with unlimited speed for testing as much as possble moves per second.
The reason why this is not practicaly is because of a phenomenon which is called "combinatorial explosion", first introduced by James Lighthill in year 1973 for prooving that artifical intelligence is not ready for use in realworld. The answer to that problem is, to use alternative strategies which have noting to do with brute-force-search.
One possibility is to use heuristics which are hardcoded into programcode. Often these heuristics are called macroaction or motion primitives. An example would be "bring-robber-to-other-side". This subfunction executes a predefined number of actions. Another macroaction could be "check-if-two-woman-are-on-the-same-side". To implement such kind of strategy for the complete game is a hard task. Not because of high cpu usage, but because of every detail has to coded into software.

How to create a reasonable AI?

I'm creating a logic game based on Fox and Hounds game. The player plays the fox and AI plays the hounds. (as far as I can see) I managed to make the AI perfect, so it never loses. Leaving it as such would not be much fun for human players.
Now, I have to dumb-down the AI so human can win, but I'm not sure how. The current AI logic is based on pattern-matching - if I introduce random moves which make the board go out of pattern space the AI would most probably play dumb until the end of the game.
I'm also thinking about removing a set of patterns, so it would seem as AI does not know that "trick" but this way players could find a way to beat the computer using the same moves every time.
Any ideas how to dumb down the AI in such way that is does not go from "genius" to "completely dumb" in a single move?
We used MinMax as the AI algorithm for our game and we implemented the AI levels by setting different depth for each level
I ended up creating a couple of quasi-smart pattern plays (as if a 10 year old might play) so it is not completely dumb, and then I pick one or two of those at random before the game starts. This way the game is always beatable, but the player does not know how (i.e. he cannot use the same strategy to always win, he has to explore for weak spot first).
If your game is a zero-sum one, the MiniMax algorithm with an alpha-beta optimization is a good choice. You can create difficulty levels by making the search stop when the algorithm reaches a certain depth.
Since I'm not an expert game developer and my AI is actually too dumb at the moment, I'd make a sort of 'learning AI'. Say you keep all your regexes disabled and you enable them once the player uses them.
I think this is a zero-sum game, and you can use the MinMax algorithm to solve the game instead of pattern matching, in that way by controlling the search depth you can control the level of expertise of the agent.
On the other hand you can use the A* search to determine the best move for a given fox/hound. And choosing different heuristics you can control the effectiveness if the agent.

Given an audio stream, find when a door slams (sound pressure level calculation?)

Not unlike a clap detector ("Clap on! clap clap Clap off! clap clap Clap on, clap off, the Clapper! clap clap ") I need to detect when a door closes. This is in a vehicle, which is easier than a room or household door:
Listen: http://ubasics.com/so/van_driver_door_closing.wav
Look:
It's sampling at 16bits 4khz, and I'd like to avoid lots of processing or storage of samples.
When you look at it in audacity or another waveform tool it's quite distinctive, and almost always clips due to the increase in sound pressure in the vehicle - even when the windows and other doors are open:
Listen: http://ubasics.com/so/van_driverdoorclosing_slidingdoorsopen_windowsopen_engineon.wav
Look:
I expect there's a relatively simple algorithm that would take readings at 4kHz, 8 bits, and keep track of the 'steady state'. When the algorithm detects a significant increase in the sound level it would mark the spot.
What are your thoughts?
How would you detect this event?
Are there code examples of sound pressure level calculations that might help?
Can I get away with less frequent sampling (1kHz or even slower?)
Update: Playing with Octave (open source numerical analysis - similar to Matlab) and seeing if the root mean square will give me what I need (which results in something very similar to the SPL)
Update2: Computing the RMS finds the door close easily in the simple case:
Now I just need to look at the difficult cases (radio on, heat/air on high, etc). The CFAR looks really interesting - I know I'm going to have to use an adaptive algorithm, and CFAR certainly fits the bill.
-Adam
Looking at the screenshots of the source audio files, one simple way to detect a change in sound level would be to do a numerical integration of the samples to find out the "energy" of the wave at a specific time.
A rough algorithm would be:
Divide the samples up into sections
Calculate the energy of each section
Take the ratio of the energies between the previous window and the current window
If the ratio exceeds some threshold, determine that there was a sudden loud noise.
Pseudocode
samples = load_audio_samples() // Array containing audio samples
WINDOW_SIZE = 1000 // Sample window of 1000 samples (example)
for (i = 0; i < samples.length; i += WINDOW_SIZE):
// Perform a numerical integration of the current window using simple
// addition of current sample to a sum.
for (j = 0; j < WINDOW_SIZE; j++):
energy += samples[i+j]
// Take ratio of energies of last window and current window, and see
// if there is a big difference in the energies. If so, there is a
// sudden loud noise.
if (energy / last_energy > THRESHOLD):
sudden_sound_detected()
last_energy = energy
energy = 0;
I should add a disclaimer that I haven't tried this.
This way should be possible to be performed without having the samples all recorded first. As long as there is buffer of some length (WINDOW_SIZE in the example), a numerical integration can be performed to calculate the energy of the section of sound. This does mean however, that there will be a delay in the processing, dependent on the length of the WINDOW_SIZE. Determining a good length for a section of sound is another concern.
How to Split into Sections
In the first audio file, it appears that the duration of the sound of the door closing is 0.25 seconds, so the window used for numerical integration should probably be at most half of that, or even more like a tenth, so the difference between the silence and sudden sound can be noticed, even if the window is overlapping between the silent section and the noise section.
For example, if the integration window was 0.5 seconds, and the first window was covering the 0.25 seconds of silence and 0.25 seconds of door closing, and the second window was covering 0.25 seconds of door closing and 0.25 seconds of silence, it may appear that the two sections of sound has the same level of noise, therefore, not triggering the sound detection. I imagine having a short window would alleviate this problem somewhat.
However, having a window that is too short will mean that the rise in the sound may not fully fit into one window, and it may apppear that there is little difference in energy between the adjacent sections, which can cause the sound to be missed.
I believe the WINDOW_SIZE and THRESHOLD are both going to have to be determined empirically for the sound which is going to be detected.
For the sake of determining how many samples that this algorithm will need to keep in memory, let's say, the WINDOW_SIZE is 1/10 of the sound of the door closing, which is about 0.025 second. At a sampling rate of 4 kHz, that is 100 samples. That seems to be not too much of a memory requirement. Using 16-bit samples that's 200 bytes.
Advantages / Disadvantages
The advantage of this method is that processing can be performed with simple integer arithmetic if the source audio is fed in as integers. The catch is, as mentioned already, that real-time processing will have a delay, depending on the size of the section that is integrated.
There are a couple of problems that I can think of to this approach:
If the background noise is too loud, the difference in energy between the background noise and the door closing will not be easily distinguished, and it may not be able to detect the door closing.
Any abrupt noise, such as a clap, could be regarded as the door is closing.
Perhaps, combining the suggestions in the other answers, such as trying to analyze the frequency signature of the door closing using Fourier analysis, which would require more processing but would make it less prone to error.
It's probably going to take some experimentation before finding a way to solve this problem.
You should tap in to the door close switches in the car.
Trying to do this with sound analysis is overengineering.
There are a lot of suggestions about different signal processing
approaches to take, but really, by the time you learn about detection
theory, build an embedded signal processing board, learn the processing
architecture for the chip you chose, attempt an algorithm, debug it, and then
tune it for the car you want to use it on (and then re-tune and re-debug
it for every other car), you will be wishing you just stickey taped a reed
switch inside the car and hotglued a magnet to the door.
Not that it's not an interesting problem to solve for the dsp experts,
but from the way you're asking this question, it's clear that sound
processing isn't the route you want to take. It will just be such a nightmare
to make it work right.
Also, the clapper is just an high pass filter fed into a threshold detector. (plus a timer to make sure 2 claps quickly enough together)
There is a lot of relevant literature on this problem in the radar world (it's called detection theory).
You might have a look at "cell averaging CFAR" (constant false alarm rate) detection. Wikipedia has a little bit here. Your idea is very similar to this, and it should work! :)
Good luck!
I would start by looking at the spectral. I did this on the two audio files you gave, and there does seem to be some similarity you could use. For example the main difference between the two seems to be around 40-50Hz. My .02.
UPDATE
I had another idea after posting this. If you can, add an accelerometer onto the device. Then correlate the vibrational and acoustic signals. This should help with cross vehicle door detection. I'm thinking it should be well correlated since the sound is vibrationally driven, wheres the stereo for example, is not. I've had a device that was able to detect my engine rpm with a windshield mount (suction cup), so the sensitivity might be there. (I make no promises this works!)
(source: charlesrcook.com)
%% Test Script (Matlab)
clear
hold all %keep plots open
dt=.001
%% Van driver door
data = wavread('van_driver_door_closing.wav');
%Frequency analysis
NFFT = 2^nextpow2(length(data));
Y = fft(data(:,2), NFFT)/length(data);
freq = (1/dt)/2*linspace(0,1,NFFT/2);
spectral = [freq' 2*abs(Y(1:NFFT/2))];
plot(spectral(:,1),spectral(:,2))
%% Repeat for van sliding door
data = wavread('van_driverdoorclosing.wav');
%Frequency analysis
NFFT = 2^nextpow2(length(data));
Y = fft(data(:,2), NFFT)/length(data);
freq = (1/dt)/2*linspace(0,1,NFFT/2);
spectral = [freq' 2*abs(Y(1:NFFT/2))];
plot(spectral(:,1),spectral(:,2))
The process for finding distinct spike in audio signals is called transient detection. Applications like Sony's Acid and Ableton Live use transient detection to find the beats in music for doing beat matching.
The distinct spike you see in the waveform above is called a transient, and there are several good algorithms for detecting it. The paper Transient detection and classification in energy matters describes 3 methods for doing this.
I would imagine that the frequency and amplitude would also vary significantly from vehicle to vehicle. Best way to determine that would be taking a sample in a Civic versus a big SUV. Perhaps you could have the user close the door in a "learning" mode to get the amplitude and frequency signature. Then you could use that to compare when in usage mode.
You could also consider using Fourier analysis to eliminate background noises that aren't associated with the door close.
Maybe you should try to detect significant instant rise in air pressure that should mark a door close. You can pair it with this waveform and sound level analysis and these all might give you a better result.
On the issue of less frequent sampling, the highest sound frequency which can be captured is half of the sampling rate. Thus, if the car door sound was strongest at 1000Hz (for example) then a sampling rate below 2000Hz would lose that sound entirely
A very simple noise gate would probably do just fine in your situation. Simply wait for the first sample whose amplitude is above a specified threshold value (to avoid triggering with background noise). You would only need to get more complicated than this if you need to distinguish between different types of noise (e.g. a door closing versus a hand clap).

Resources