Hi guys,
Today we are going to see, TIC-TAC-TOE GAME DEVELOPMENT USING LIGHTNING COMPONENT
Output -:
Create a static resource to store Image-X and Image-O
Use Below Image for Image-X
Use Below Image for Image-O
TicTakToe.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<aura:attribute name="showImage" type="String" default="show-x"/>
<aura:attribute name="tile1" type="String" default="tile1"/>
<aura:attribute name="tile2" type="String" default="tile2"/>
<aura:attribute name="tile3" type="String" default="tile3"/>
<aura:attribute name="tile4" type="String" default="tile4"/>
<aura:attribute name="tile5" type="String" default="tile5"/>
<aura:attribute name="tile6" type="String" default="tile6"/>
<aura:attribute name="tile7" type="String" default="tile7"/>
<aura:attribute name="tile8" type="String" default="tile8"/>
<aura:attribute name="tile9" type="String" default="tile9"/>
<aura:attribute name="player1" type="String"/>
<aura:attribute name="player2" type="String"/>
<aura:attribute name="gameCompleted" type="boolean" default="false"/>
<aura:attribute name="gameResultModal" type="boolean" default="false"/>
<aura:attribute name="gameResultMessage" type="boolean" default="true"/>
<aura:attribute name="playerSelectionModal" type="boolean" default="true"/>
<lightning:card>
<div class="slds-align_absolute-center">
<div class="slds-box">
<fieldset class="slds-form-element">
<div class="slds-form-element__control">
<div class="slds-grid slds-gutters">
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile1" type="radio" id="visual-picker-85" name="options" value="tile1" onclick="{! c.handleOnClick }" />
<label for="visual-picker-85">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile1o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile1x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile2" type="radio" id="visual-picker-86" value="tile2" name="options" onclick="{! c.handleOnClick }" />
<label for="visual-picker-86">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile2o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile2x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile3" type="radio" id="visual-picker-87" value="tile3" name="options" onclick="{! c.handleOnClick }" />
<label for="visual-picker-87">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile3o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile3x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
</div>
<div class="slds-grid slds-gutters">
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile4" type="radio" id="visual-picker-88" name="options" value="tile4" onclick="{! c.handleOnClick }" />
<label for="visual-picker-88">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile4o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile4x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile5" type="radio" id="visual-picker-89" value="tile5" name="options" onclick="{! c.handleOnClick }" />
<label for="visual-picker-89">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile5o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile5x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile6" type="radio" id="visual-picker-90" value="tile6" name="options" onclick="{! c.handleOnClick }" />
<label for="visual-picker-90">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile6o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile6x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
</div>
<div class="slds-grid slds-gutters">
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile7" type="radio" id="visual-picker-91" name="options" value="tile7" onclick="{! c.handleOnClick }" />
<label for="visual-picker-91">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile7o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile7x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile8" type="radio" id="visual-picker-92" value="tile8" name="options" onclick="{! c.handleOnClick }" />
<label for="visual-picker-92">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile8o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile8x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
<div class="slds-col">
<div class="slds-visual-picker slds-visual-picker_medium">
<input aura:id="tile9" type="radio" id="visual-picker-93" value="tile9" name="options" onclick="{! c.handleOnClick }" />
<label for="visual-picker-93">
<span class="slds-visual-picker__figure slds-visual-picker__text slds-align_absolute-center">
<span>
<span class="slds-icon_container">
<span class="slds-icon_container">
<lightning:card class="slds-hide" aura:id="tile9o">
<img src="{!$Resource.Image_O}" style="width:140px; height:140px;"/>
</lightning:card>
<lightning:card class="slds-hide" aura:id="tile9x">
<img src="{!$Resource.Image_X}" style="width:140px; height:140px;"/>
</lightning:card>
</span>
</span>
</span>
</span>
<span class="slds-visual-picker__body">
<span class="slds-text-heading_small"></span>
</span>
</label>
</div>
</div>
</div>
</div>
</fieldset>
</div>
</div>
</lightning:card>
<aura:if isTrue="{!v.playerSelectionModal}">
<!-- Modal/Popup Box starts here-->
<section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<!-- Modal/Popup Box Header Starts here-->
<header class="slds-modal__header">
<h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Play Tic-Tac-Toe</h2>
</header>
<!--Modal/Popup Box Body Starts here-->
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<p><b>
<lightning:layout>
<lightning:layoutitem padding="around-small" size="6">
Player 1 :
<lightning:select name="player1" value="{!v.player1}" label="" onchange="{!c.onPlayer1Change}" >
<option value="X">X</option>
<option value="O">O</option>
</lightning:select>
</lightning:layoutitem>
<lightning:layoutitem padding="around-small" size="6">
Player 2 :
<lightning:select name="player2" value="{!v.player2}" label="" onchange="{!c.onPlayer2Change}">
<option value="O">O</option>
<option value="X">X</option>
</lightning:select>
</lightning:layoutitem>
</lightning:layout>
</b>
</p>
</div>
<!--Modal/Popup Box Footer Starts here-->
<footer class="slds-modal__footer">
<lightning:button variant="brand"
label="OK"
title="OK"
onclick="{!c.submitDetails}"/>
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</aura:if>
<aura:if isTrue="{!v.gameResultModal}">
<!-- Modal/Popup Box starts here-->
<section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<!-- Modal/Popup Box Header Starts here-->
<header class="slds-modal__header">
<h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Play Tic-Tac-Toe </h2>
</header>
<!--Modal/Popup Box Body Starts here-->
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<p><b><div class="slds-align_absolute-center">
{!v.gameResultMessage}
</div>
</b>
</p>
</div>
<!--Modal/Popup Box Footer Starts here-->
<footer class="slds-modal__footer">
<lightning:button variant="brand"
label="Play Again"
title="Restart"
onclick="{!c.restart}"/>
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</aura:if>
</aura:component>
----------------------------------------------------------------------------------
TicTakToe.js
({
handleOnClick : function(component, event, helper) {
var showImage = component.get('v.showImage');
if(showImage == 'show-x'){
if(event.srcElement.value == 'tile1'){
if(component.find('tile1x').get('v.class') == 'slds-hide' && component.find('tile1o').get('v.class') == 'slds-hide')
{
component.find('tile1x').set('v.class','slds-show');
component.find('tile1o').set('v.class','slds-hide');
component.set('v.tile1','x');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile2'){
if(component.find('tile2x').get('v.class') == 'slds-hide' && component.find('tile2o').get('v.class') == 'slds-hide')
{
component.find('tile2x').set('v.class','slds-show');
component.set('v.tile2','x');
component.find('tile2o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile3'){
if(component.find('tile3x').get('v.class') == 'slds-hide' && component.find('tile3o').get('v.class') == 'slds-hide')
{
component.find('tile3x').set('v.class','slds-show');
component.set('v.tile3','x');
component.find('tile3o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile4'){
if(component.find('tile4x').get('v.class') == 'slds-hide' && component.find('tile4o').get('v.class') == 'slds-hide')
{
component.find('tile4x').set('v.class','slds-show');
component.set('v.tile4','x');
component.find('tile4o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile5'){
if(component.find('tile5x').get('v.class') == 'slds-hide' && component.find('tile5o').get('v.class') == 'slds-hide')
{
component.find('tile5x').set('v.class','slds-show');
component.set('v.tile5','x');
component.find('tile5o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile6'){
if(component.find('tile6x').get('v.class') == 'slds-hide' && component.find('tile6o').get('v.class') == 'slds-hide')
{
component.find('tile6x').set('v.class','slds-show');
component.set('v.tile6','x');
component.find('tile6o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile7'){
if(component.find('tile7x').get('v.class') == 'slds-hide' && component.find('tile7o').get('v.class') == 'slds-hide')
{
component.find('tile7x').set('v.class','slds-show');
component.set('v.tile7','x');
component.find('tile7o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile8'){
if(component.find('tile8x').get('v.class') == 'slds-hide' && component.find('tile8o').get('v.class') == 'slds-hide')
{
component.find('tile8x').set('v.class','slds-show');
component.set('v.tile8','x');
component.find('tile8o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
else if(event.srcElement.value == 'tile9'){
if(component.find('tile9x').get('v.class') == 'slds-hide' && component.find('tile9o').get('v.class') == 'slds-hide')
{
component.find('tile9x').set('v.class','slds-show');
component.set('v.tile9','x');
component.find('tile9o').set('v.class','slds-hide');
component.set('v.showImage','show-o');
}
}
}else{
if(event.srcElement.value == 'tile1'){
if(component.find('tile1x').get('v.class') == 'slds-hide' && component.find('tile1o').get('v.class') == 'slds-hide')
{
component.find('tile1o').set('v.class','slds-show');
component.set('v.tile1','o');
component.find('tile1x').set('v.class','slds-hide');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile2'){
if(component.find('tile2x').get('v.class') == 'slds-hide' && component.find('tile2o').get('v.class') == 'slds-hide')
{
component.find('tile2x').set('v.class','slds-hide');
component.find('tile2o').set('v.class','slds-show');
component.set('v.tile2','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile3'){
if(component.find('tile3x').get('v.class') == 'slds-hide' && component.find('tile3o').get('v.class') == 'slds-hide')
{
component.find('tile3x').set('v.class','slds-hide');
component.find('tile3o').set('v.class','slds-show');
component.set('v.tile3','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile4'){
if(component.find('tile4x').get('v.class') == 'slds-hide' && component.find('tile4o').get('v.class') == 'slds-hide')
{
component.find('tile4x').set('v.class','slds-hide');
component.find('tile4o').set('v.class','slds-show');
component.set('v.tile4','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile5'){
if(component.find('tile5x').get('v.class') == 'slds-hide' && component.find('tile5o').get('v.class') == 'slds-hide')
{
component.find('tile5x').set('v.class','slds-hide');
component.find('tile5o').set('v.class','slds-show');
component.set('v.tile5','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile6'){
if(component.find('tile6x').get('v.class') == 'slds-hide' && component.find('tile6o').get('v.class') == 'slds-hide')
{
component.find('tile6x').set('v.class','slds-hide');
component.find('tile6o').set('v.class','slds-show');
component.set('v.tile6','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile7'){
if(component.find('tile7x').get('v.class') == 'slds-hide' && component.find('tile7o').get('v.class') == 'slds-hide')
{
component.find('tile7x').set('v.class','slds-hide');
component.find('tile7o').set('v.class','slds-show');
component.set('v.tile7','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile8'){
if(component.find('tile8x').get('v.class') == 'slds-hide' && component.find('tile8o').get('v.class') == 'slds-hide')
{
component.find('tile8x').set('v.class','slds-hide');
component.find('tile8o').set('v.class','slds-show');
component.set('v.tile8','o');
component.set('v.showImage','show-x');
}
}
else if(event.srcElement.value == 'tile9'){
if(component.find('tile9x').get('v.class') == 'slds-hide' && component.find('tile9o').get('v.class') == 'slds-hide')
{
component.find('tile9x').set('v.class','slds-hide');
component.find('tile9o').set('v.class','slds-show');
component.set('v.tile9','o');
component.set('v.showImage','show-x');
}
}
}
var tile1 = component.get('v.tile1');
var tile2 = component.get('v.tile2');
var tile3 = component.get('v.tile3');
var tile4 = component.get('v.tile4');
var tile5 = component.get('v.tile5');
var tile6 = component.get('v.tile6');
var tile7 = component.get('v.tile7');
var tile8 = component.get('v.tile8');
var tile9 = component.get('v.tile9');
if(((tile1 == tile2) && (tile1 == tile3)) || ((tile1 == tile4) && (tile1 == tile7))
|| ((tile1 == tile5) && (tile1 == tile9)) || ((tile3 == tile5) && (tile3 == tile7))
|| ((tile2 == tile5) && (tile2 == tile8)) || ((tile4 == tile5) && (tile4 == tile6))
|| ((tile7 == tile8) && (tile8 == tile9)) || ((tile3 == tile6) && (tile3 == tile9))){
if(showImage == 'show-x'){
if(component.get('v.player1') == 'X'){
component.set('v.gameResultModal',true);
component.set('v.gameResultMessage','Player 1 won the match')
}else{
component.set('v.gameResultModal',true);
component.set('v.gameResultMessage','Player 2 won the match')
}
}else{
if(component.get('v.player2') == 'O'){
component.set('v.gameResultModal',true);
component.set('v.gameResultMessage','Player 2 won the match');
}else{
component.set('v.gameResultModal',true);
component.set('v.gameResultMessage','Player 1 won the match');
}
}
component.set('v.gameCompleted',true);
}
if(component.get('v.gameCompleted') == false && tile1 != 'tile1' && tile2 != 'tile2' && tile3 != 'tile3' && tile4 != 'tile4' && tile5 != 'tile5' && tile6 !='tile6'
&& tile7 != 'tile7' && tile8 != 'tile8' && tile9 != 'tile9') {
component.set('v.gameResultModal',true);
component.set('v.gameResultMessage','Game Tied')
}
},
submitDetails: function(component, event, helper) {
if(component.get('v.player1') == 'X'){
component.set('v.showImage','show-x');
}else{
component.set('v.showImage','show-o');
}
component.set("v.playerSelectionModal", false);
},
onPlayer1Change: function(component, event, helper) {
if(component.get('v.player1') == 'X'){
component.set('v.player2','O');
}else{
component.set('v.player2','X');
}
},
onPlayer2Change: function(component, event, helper) {
if(component.get('v.player2') == 'X'){
component.set('v.player1','O');
}else{
component.set('v.player1','X');
}
},
restart: function(component, event, helper) {
location.reload();
}
})
TicTakToeApp.app
<aura:application extends="force:slds">
<c:TicTakToe/>
</aura:application>